Building a custom storefront
Adobe Commerce can operate as a headless commerce platform that’s decoupled from its storefront. You can use the REST API or GraphQL API to build custom storefronts, such as progressive web apps (PWA), mobile apps, or frontends based on React, Vue, or other frameworks.
The Stripe module extends the REST API and GraphQL API with the following functionality:
- Setting payment method tokens during order placement
- Performing 3D Secure customer authentication
- Managing customers’ saved payment methods
The Stripe module uses the REST API on the checkout page. You can find examples of how to use the API in the Stripe module directory under the examples/
subdirectory.
The following example uses the GraphQL API to build a custom storefront.
Tokenize a payment method during the checkout flow
You can use the PaymentElement to collect a payment method from the customer during checkout. After the customer provides their payment method details and clicks Place Order, you can tokenize the payment method and use it to place the order. Calling createPaymentMethod
generates a payment method token from the details provided in the PaymentElement
.
var stripe = Stripe(API_PUBLISHABLE_KEY); var options = { mode: 'payment', amount: 1099, currency: 'eur' }; var elements = stripe.elements(options); var paymentElement = elements.create('payment'); paymentElement.mount('#payment-element'); var placeOrder = function() { elements.submit().then(function() { stripe.createPaymentMethod({ elements: elements, params: { billing_details: { name: 'Jenny Rosen' } } }).then(function(result) { if (result && result.paymentMethod) { // Success } }); }); }
Pass the tokenized payment method
After you obtain a payment method token, you must call setPaymentMethodOnCart
to set the payment method on the order.
mutation { setPaymentMethodOnCart(input: { cart_id: "CART_ID" payment_method: { code: "stripe_payments" stripe_payments: { payment_element: true payment_method: "PAYMENT_METHOD_ID" save_payment_method: true } } }) { cart { selected_payment_method { code } } } }
Use the following parameters for setPaymentMethodOnCart
:
Parameter | Type | Description |
---|---|---|
payment_element | Boolean | Set this to true if you use the PaymentElement on the frontend. This differs from other flows, such as admin orders, the multi-shipping page, or legacy flows. |
payment_method | String | Use this parameter to pass the tokenized payment method ID. You can also pass saved payment method tokens when a customer chooses a saved payment method during checkout. |
save_payment_method | Boolean | Specify whether or not to save the payment method. |
manual_authentication | String | Use this parameter to specify the comma-separated list of payment methods to perform manual customer authentication on. Orders are placed after you manually authenticate a customer. |
cvc_token | String | If CVC is enabled for saved cards, use this parameter to pass the CVC token and perform verification. |
cc_stripejs_token | String | This parameter is deprecated but maintained for backwards compatibility. If you use the CardElement or another tokenization method that isn’t the PaymentElement , set payment_element to false and pass the payment method ID. |
Place the order
After you set the payment method token, you can use the Adobe Commerce placeOrder
mutation to place an order:
mutation { placeOrder(input: {cart_id: "CART_ID"}) { order { order_number client_secret } } }
The example above requests a client_secret
, which isn’t a default placeOrder
mutation parameter. The Stripe module adds this parameter for you to use after the order is placed to finalize details specific to the selected payment method. You can finalize payment with the stripe.handleNextAction(client_secret)
method. Options include performing an inline 3D Secure authentication for cards, displaying a printable voucher for certain payment methods, or redirecting the customer externally for authentication.
Manual authentication
Payment methods that require customer authentication go through the following process:
- The order is placed in pending status.
- Control is passed to the frontend to perform the authentication.
- After successful authentication, payment is collected.
- A
charge.succeeded
webhook event passes to your website. - The module handles the event, and changes the order status from pending to processing.
Card payments receive synchronous payment confirmation, so you can wait to place an order until after the payment succeeds. To do so, pass the manual_authentication
parameter on the setPaymentMethodOnCart
mutation: 'manual_authentication': "card"
If customer authentication is required and you pass this parameter, the order won’t be placed and the frontend receives an error with the client_secret
. You can then use the client_secret
to manually authenticate the payment and call the placeOrder
mutation after a successful authentication. The second order placement creates and saves the order in a processing status using the already successful payment.
Retrieve saved payment methods
You can use listStripePaymentMethods
to retrieve a list of saved payment methods for a customer in an active checkout session.
mutation { listStripePaymentMethods { id created type fingerprint label icon cvc brand exp_month exp_year } }
Save a payment method
You can use addStripePaymentMethod
to save payment methods to a customer’s account. The payment_method
parameter is the tokenized payment method ID. The tokenization process is similar to the tokenization process during the checkout flow.
mutation { addStripePaymentMethod( input: { payment_method: "PAYMENT_METHOD_ID" } ) { id created type fingerprint label icon cvc brand exp_month exp_year } }
Delete a saved payment method
You can use deleteStripePaymentMethod
to allow customers to delete saved payment methods from their account.
For most use cases, we recommend passing a payment method fingerprint, which deletes all payment methods that match the fingerprint. The listStripePaymentMethods
mutation automatically removes duplicates before returning recently added payment methods that match a specific fingerprint. But if you only delete a payment method by ID, the results of listStripePaymentMethods
might include an older saved payment method with the same fingerprint.
mutation { deleteStripePaymentMethod( input: { payment_method: "paste a payment method ID here" fingerprint: null } ) }