Dai balanceof showing 0 for my address after successful Uniswap swap transaction on Ganache - ganache

I am using Ganache to test out real smart contracts and protocols like minting a NFT, Uniswap , AAve etc. When I run a transaction to mint a NFT I am able to see NFT in my wallet connected to Ganache. Also when I run a wrap transaction on Uniswap I see the weth in my wallet connected with Ganache, but when I do a Uniswap swap I do not see the swapped token in my wallet. The transaction was successful and Eth got deducted but I don't see the token (for ex Dai) that I swapped for Eth. I also tried with other tokens but their balance did not change. Is there something I am doing wrong?
Here is the transaction:
curl -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0", "id": 1, "method": "eth_sendTransaction", "params": [{"from":"0x4a4c43230e64b397f6A0f11C8714f880741d5A9D", "to":"0xcc9a0B7c43DC2a5F023Bb9b738E45B0Ef6B06E04", "value":"0x2C68AF0BB140000", "gas":"0x6691B7", "data":"0x474cf53d0000000000000000000000007d2768de32b0b80b7a3454c06bdac94a69ddc7a9000000000000000000000000ce8646f859769e8be39103f2fe14641502ec36d30000000000000000000000000000000000000000000000000000000000000000"}] }' http://localhost:8545
Here is the debug trace:
CALL address 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, gas 6696889, value 200000000000000000, payload d0e30db0
CALL address 0x7d2768de32b0b80b7a3454c06bdac94a69ddc7a9, gas 6663204, value 0, payload e8eda9df000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000002c68af0bb140000000000000000000000000000ce8646f859769e8be39103f2fe14641502ec36d30000000000000000000000000000000000000000000000000000000000000000
DELEGATECALL address 0xc6845a5c768bf8d7681249f8927877efda425baf, gas 6556508, payload e8eda9df000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000002c68af0bb140000000000000000000000000000ce8646f859769e8be39103f2fe14641502ec36d30000000000000000000000000000000000000000000000000000000000000000
DELEGATECALL address 0xf5543cdd5f551635e13ebe07e47d01d0fc9cbbd5, gas 6445852, payload 0eca322b4cb5a02f592bd29403ce60c982c7f5174b16842da4fff5cfd025d6836dc48d4b00000000000000000000000000000000000000000000000002c68af0bb140000
STATICCALL address 0xf63b34710400cad3e044cffdcab00a0f32e33ecf, gas 6436009, payload b1bf962d
DELEGATECALL address 0xddde1fa049209bc24b69d5fa316a56efec918d79, gas 6332881, payload b1bf962d
RETURN: 000000000000000000000000000000000000000000005c56cd3725d693df1415
RETURN: 000000000000000000000000000000000000000000005c56cd3725d693df1415
STATICCALL address 0x4e977830ba4bd783c0bb7f15d3e243f73ff57121, gas 6406629, payload 79774338
DELEGATECALL address 0xa558ea1a875f8b576f0728d32c39f62158e49b92, gas 6303952, payload 79774338
RETURN: 0000000000000000000000000000000000000000000000102fd6f1b3ffc7187a0000000000000000000000000000000000000000000000103005d97e16fa5c34000000000000000000000000000000000000000000262e32dc3533a3b969ae6b00000000000000000000000000000000000000000000000000000000627d6bf8
RETURN: 0000000000000000000000000000000000000000000000102fd6f1b3ffc7187a0000000000000000000000000000000000000000000000103005d97e16fa5c34000000000000000000000000000000000000000000262e32dc3533a3b969ae6b00000000000000000000000000000000000000000000000000000000627d6bf8
CALL address 0x030ba81f1c18d280636f32af80b9aad02cf0854e, gas 6385329, value 0, payload 7df5bd3b0000000000000000000000000000000000000000000000000004d8e49050c95d000000000000000000000000000000000000000003422fe111e9efa9202a2f0b
DELEGATECALL address 0x541dcd3f00bcd1a683cc73e1b2a8693b602201f4, gas 6282987, payload 7df5bd3b0000000000000000000000000000000000000000000000000004d8e49050c95d000000000000000000000000000000000000000003422fe111e9efa9202a2f0b
CALL address 0xd784927ff2f95ba542bfc824c8a8a98f3495f6b5, gas 6168206, value 0, payload 31873e2e000000000000000000000000464c71f6c2f760dda6093dcb91c24c39e5d6e18c00000000000000000000000000000000000000000000fdf26cd315339f1a1a070000000000000000000000000000000000000000000000085d593d262b2bbb1f
DELEGATECALL address 0x83d055d382f25e6793099713505c68a5c7535a35, gas 6069251, payload 31873e2e000000000000000000000000464c71f6c2f760dda6093dcb91c24c39e5d6e18c00000000000000000000000000000000000000000000fdf26cd315339f1a1a070000000000000000000000000000000000000000000000085d593d262b2bbb1f
RETURN:
RETURN:
STATICCALL address 0x4e977830ba4bd783c0bb7f15d3e243f73ff57121, gas 6331984, payload f731e9be
DELEGATECALL address 0xa558ea1a875f8b576f0728d32c39f62158e49b92, gas 6232479, payload f731e9be
RETURN: 0000000000000000000000000000000000000000000000103005d97e16fa5c34000000000000000000000000000000000000000000262e32dc3533a3b969ae6b
RETURN: 00000000000000000000000

Related

How to update credit card payment in stripe

I have a flow using nodejs and reactjs to let users subscribe to my site.
So when user logs in he can see a few packages.
When the user selects a package and enters card details, I do the following:
1 - Create a new customer, based on user details (name, email etc, fetched since user logged in)
2 - Create a subscription for the newly create customer according to price_id selected
3 - Collect in the frontend the card number/cvc/expire date with:
const cardElement = elements.getElement(CardElement);
4 - Make a call to stripe from frontend with:
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: name,
}
}
});
Im not sure if this was the best flow. However, it is working.
I also managed updating subscription and canceling it.
However, Im having an hard time in changing credit card details.
What I understood from docs I should use the same call as I did when I create the card payment.
So I collect again the credit card number and call again the same function:
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: name,
}
}
});
However, the call is done to:
https://api.stripe.com/v1/payment_intents/pi_XXXX/confirm
and returns a 400 with this info:
type: "invalid_request_error", code: "payment_intent_unexpected_state", doc_url: "https://stripe.com/docs/error-codes/payment-intent-unexpected-state"
Should I use something else to update credit card info? Or am I calling it in the wrong way?
Your initial flow of calling confirmCardPayment() is correct, that is what is recommended in Stripe's docs too: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements.
hard time in changing credit card details. What I understood from docs I should use the same call as I did when I create the card payment.
To just collect card details and create a PaymentMethod, you should call createPaymentMethod() [0] from Stripe.js. That will convert a customer's card into a PaymentMethod like pm_123.
You will then send that PaymentMethod to your backend server, where (using your server-side Stripe API library like stripe-node) you'll attach it to a Stripe Customer [1] and also update as the Customer's default PaymentMethod for recurring payments [2].
[0] https://stripe.com/docs/js/payment_methods/create_payment_method
[1] https://stripe.com/docs/api/payment_methods/attach
[2] https://stripe.com/docs/api/customers/update#update_customer-invoice_settings-default_payment_method

Insufficient funds in Stripe even with funds and manual payouts enabled

I am having trouble to make transfer from a paymentIntent, I have enabled manual payouts and have funds in my test balance..
I tried also to add source_transaction in the transfer object, but without success
I am getting:
StripeInvalidRequestError: Insufficient funds in Stripe account. In
test mode, you can add funds to your available balance (bypassing your
pending balance) by creating a charge with 4000 0000 0000 0077 as the
card number
I already added with this test card number..
The paymentIntent is created successfully:
const paymentIntent = await stripe.paymentIntents.create(
{
amount: amount,
currency: "usd",
payment_method_types: ["card"],
transfer_group: "{ORDER11}",
}
)
And here is my failing transfer object:
const transfer = await stripe.transfers.create({
amount: orderAmount,
currency: "usd",
destination: sellerAccountId,
transfer_group: "{ORDER11}",
source_transaction: pi.charges.data.id,
});
Thank you for helping
Just make sure, was this payment intent confirmed and did does it have status=succeeded (API ref)?
You may just have a small error in your source_transaction which needs to be pi.charges.data**[0]**.id, since data is an array you must provide an index.

Collect an email address with Stripe

I'm following https://stripe.com/docs/payments/accept-a-payment and it works.
I need to collect a customer email address. I am using the client-server integration, as I believe this is necessary to support a dynamic price, set with the following code:
router.post("/create-payment-intent", async (req, res) => {
const stripe = require("stripe")("redacted");
const { items } = req.body;
// Create a PaymentIntent with the order amount and currency
const paymentIntent = await stripe.paymentIntents.create({
amount: calculateOrderAmount(items),
currency: "usd"
});
res.send({
clientSecret: paymentIntent.client_secret
});
});
I've been very confused by the documentation. (I've previously used PayPal for payments, which has its own issues.)
How can I collect an email address, as part of the Stripe checkout process?
Could someone point me at the correct page?
You'd collect the email address yourself, using a HTML element on your checkout page. You then have the choice to create a Stripe customer with this information and pass that into your PaymentIntent creation if you wish to reuse the customer later. Or you can just pass the email address in the receipt_email field when creating the PaymentIntent.

create charge for existing customer with different card

So i have a customer which already has a card created.
On the frontend, i give the option to use the existing card or a different one.
Following the API docs, for the new card, i create the token, send it to my backend...
In the backend:
const paymentInfo = {
customer: customerId,
amount: Number(total) * 100,
currency: 'usd',
source: existingCardId || token
}
const charge = await stripe.charges.create(paymentInfo)
If i pay with the existing card, the charge goes through, but if i send a new token, I get an error back:
Customer cus_G4V0KvxKMmln01 does not have a linked source with ID tok_1FYMLTAOg97eusNI2drudzlJ.
From the API Docs:
https://stripe.com/docs/api/charges/create
source optional A payment source to be charged. This can be the ID of
a card (i.e., credit or debit card), a bank account, a source, a
token, or a connected account. For certain sources—namely, cards, bank
accounts, and attached sources—you must also pass the ID of the
associated customer.
I found the solution:
if (token) {
const card = await stripe.customers.createSource(customerId, {
source: token
})
paymentInfo.source = card.id
}

PDS2 Stripe Success Webhook and other issues

This is in danger of being TLDR - so my question is: On successful payment - stripes sends a "success" payload to my success webhook. Looking through the payload, I am unable to see anything which I can use to find which payment was successful. Should I be saving something from my stripe session to my pending payment?
Greater detail:
To comply with PSD2, I've had to rejig our stripe payments. We support a few different payment options, which has affected how I go about the process.
Before, with stripe, we'd get a token - send it client side... payment made - order saved to DB.. job done.
Now, the flow is reversed...
I have a "Stripe" button - customer clicks on it. A POST is made to the server. On the server I grab the customers cart and create an order with a payment status of pending.
I then create a stripe session - and return the stripe session ID to the client (code is abridged)
//creates order and returns Order ID
const orderid = await createOrder(cart);
const stripeSession = await stripe.checkout.sessions.create({
customer_email: request.payload.billingEmail,
payment_method_types: ["card"],
line_items: [
{
name: "###",
description: "###" + orderid,
amount: cart.total.total,
currency: cart.total.currency,
quantity: 1
}
],
success_url: "###" + orderid,
cancel_url: "###/checkout"
});
return {
stripeSessionID: stripeSession.id
};
and on my client I have this method method to post to the server and automatically redirect to external stripe checkout page:
stripeCheckout: function () {
...
axios.post('/pay/get-stripe-session', data)
.then(function (response) {
var checkoutSessionID = response.data.stripeSessionID
stripe.redirectToCheckout({
sessionId: checkoutSessionID
}) ...
Upon succesful payment, stripe sends a "success" payload to my success webhook. I check the stripe signature - and receive the message... this all works... however, I can't see any data in the payload that I can use to match the payment with the order (in order to update the orders payment status).
When I create my stripe session is there anything from it that I can use?
** Edit ** -
When creating a stripe session, one can pass client_reference_id. into the create session method as a unique key. However, stripes success webhook does NOT return this key in its payload - so this cannot be used to reconcile a successful payment with an order.
We have our own customer accounts system. Under the old API we could set up a charge thus:
const charge = await stripe.charges.create({
amount: total,
currency: currency,
source: token, // obtained with Stripe.js
description: orderid
})
And the description would appear in stripes dashboard making it easy to find a payment (to make a refund or whatever). We don't use Stripes 'customers'. We store orders, and customers in our system (stripe is not a customer management system). If the customer is logged in when they check out, we link them to their order. Guest orders aren't linked to anyone.
However, under the new api where you have to create a stripeSession every session creates a customer in stripes dashboard. Can we prevent this?
Also, there is no way to add a description to the overall session / charge like you could with the old charge api - so in Stripes Payments dashboard, we end up with unusable junk for each payment description...
Does anyone know how to fix this? I hope stripe aren't having to sacrifice their wonderful developer experince to comply with PDS2
When you create the CheckoutSession, you can pass it a client_reference_id. That value will be present on the object later for you to reference an order in your own systems.
Solved it:
The trick is to set meta-data on your stripe session:
const stripeSession = await stripe.checkout.sessions.create({
customer_email: billingEmail,
client_reference_id: orderid,
payment_method_types: ["card"],
line_items: [
{
name: "My charge",
description: "Lorem ipsum",
amount: total,
currency: currency,
quantity: 1
}
],
payment_intent_data: {
description: `orderID: ${orderid}`,
metadata: {
orderid : orderid
}
},
success_url: "https://example.com/thankyou/",
cancel_url: "https://example.com/checkout"
});
The metadata is returned in the charge.success event (webhook). Using this metadata, I am able to find the order in my database and update it. In our case, I take the transaction.id, card type and last 4 card digits from the charge.success event and update the payment status to paid.
If you don't need this information - you could simply set your webhook to receive the checkout.session.complete event as that contains the client_reference_id (and I believe is stripes preferred event to confirm a transaction)
Because we're not using Customers accounts inside Stripe, I also remove the customer from stripe:
// Delete the customer from Stripes Dashboard (we don't use it - its clutter)
const customerID = event.data.object.customer
stripe.customers.del(
customerID,
function(err, confirmation) {
// asynchronously called
}
);
And thats basically it. Use the meta - it seems to be sent on every event.

Resources