1
votes

As you see my question i am confused because i saw many article and stripe documentation solutions for saving card every time i get something different. My application flow is something like that first user come and he will be given 2 options

  1. previous saved cards
  2. enter new card

Enter New card

In doing this i take card details from customer and then i am generating token and sending that token and customerId that will be fetched from db(if old customer) and it means that customer is already generated and at backend i create customer first(if no customerId found) using the stripe token i get after adding payment information and then use the customerId i will charge the customer

stripe.charges.create({
        amount:amount,
        description: '',
        currency: 'usd',
        customer: customerid
      })

Now here my question starts

I cannot use the token i got after adding payment details because that token is only for one time and I cannot use customerId directly to charge the customer then how I can charge the customer in future and how can i get a list of customers saved payment methods and delete or update them.

3

3 Answers

2
votes

Stripe support few options for storing card details. You can store paymentMethod after initial payment or store card details and then pay.

To store card details before payment:

  1. Crete StripeCustomer

CustomerCreateParams params = CustomerCreateParams.builder()
            .setName("Customer name")
            .setEmail("customer@email")
            .build();
Customer customer = Customer.create(params);
  1. Prepare SetupIntent object on backend

SetupIntentCreateParams setupIntentCreateParams = SetupIntentCreateParams.builder().setCustomer(customer.getId()).build();
SetupIntent intent = SetupIntent.create(setupIntentCreateParams);
return new PrepareSetupResponse(intent.getClientSecret());
  1. Send intent.getClientSecret() as prepareSetupResponse.data.clientSecret to frontend

  2. Send stripe.confirmCardSetup and use result.setupIntent.payment_method to create PaymentIntent on backend

    .setOffSession(true).setConfirm(true); is important for offline payments

Builder paramsBuilder = builder()
            .setCurrency("USD")
            .addPaymentMethodType("card")
            .setOffSession(true)
            .setConfirm(true);
            .setPaymentMethod(confirmSubscriptionRequest.getPaymentMethod())
            .setCustomer(customer.getId());
            
PaymentIntent intent = PaymentIntent.create(paymentIntentParameters.build());

Complete JS side example

axios.post(prepareSetupUrl).then(prepareSetupResponse => {
      if (prepareSetupResponse.status === 200) {
        const clientSecret = prepareSetupResponse.data.clientSecret;
        stripe.confirmCardSetup(clientSecret, {
          payment_method: {
            card: elements.getElement(CardElement),
            billing_details: {
              name: "cardholder name"
            }
          }
        }).then(result => {
          if (result.setupIntent && result.setupIntent.payment_method) {
            axios.post(preparePaymentUrl, {
              paymentMethod: result.setupIntent.payment_method
            }).then((confirmPaymentResponse) => {
              if (confirmPaymentResponse.status === 200) {
                this.props.history.push("/checkout/success");
              } else {
                this.props.history.push("/checkout/failed");
                console.log(confirmPaymentResponse.statusText);
              }
            }).catch(exception => {
              console.log(exception);
              this.props.history.push("/checkout/failed");
            });
          } else {
            that.props.history.push("/checkout/failed");
          }
        });
      }
1
votes

When you receive a token from Stripe, that token should then be used in a subsequent call to create a customer with that token. You can do so using the stripe.customers.create call. This will then convert that token into a source you can repeatedly use. See: https://stripe.com/docs/api/customers/create#create_customer-source

When you retrieve that customer the next time around, you'll notice that the source persists in the customer object. See: https://stripe.com/docs/api/customers/retrieve

When creating another charge, use that new source_id found within the customer object instead of the source parameter. If you do not provide one, it'll use the default one set for that customer.

If you need to add additional cards to a customer, use the Card Creation API. This will allow you to create, update, and delete cards for a customer. See: https://stripe.com/docs/api/cards/create

1
votes

First, when your customer adds a card on frontend, you can save it as a payment method and use it for later.

Frontend:

const result = await stripe.createPaymentMethod({
    type: 'card',
    card: cardElement,
    billing_details: {
        // Some details of your customer like email, name, etc
    },
});

And you have to send the result.paymentMethod.id to backend and create stripe customer with that paymentMethod.

stripe.customers.create({
    email: emailAddress,
    invoice_settings: {
        default_payment_method: paymentMethodId,
    },
    payment_method: paymentMethodId,
});
// paymentMethodId is the payment method id passed from frontend

You can check the below documents:

https://stripe.com/docs/payments/save-and-reuse

https://stripe.com/docs/payments/save-during-payment

Note: You can only save the id of customer in your database and stripe will handle all of the others. You don't have to try to save something in your database for later usage.