How to add Braintree as a payment provider
Braintree is a payment processing platform owned by PayPal, providing online and mobile payment solutions for businesses of all sizes.
Prerequisites
- Add Braintree as a payment provider through the Admin tool.
Checkout flow
The checkout workflow using Braintree follows the steps defined on Checkout to purchase a subscription. The code provided below is explained according to the regular checkout flow.
Regardless of the payment provider, Steps 1
to 5
(Authenticate, Get products and prices, Add item(s) to cart, Create order and Get payment options) are exactly the same as described on Checkout to purchase a subscription. See How to add Stripe Intents as a payment provider for implementation details.
-
Authenticate
. -
Get products and prices
. -
Add item(s) to cart
. -
Create order
. -
Get payment options
. -
Initialize payment
: On the previous step, you can identify payment methods set up for Braintree by checking if they have paymentMethodType: 15. For each element returned, you will see a paymentMethodID, this value, together with the orden number are required when callingSales.initializePayment()
.const orderNumber = Sales.currentOrder.orderNumber;const paymentProvider = chosenPaymentOption; // chosen by the user with paymentMethodType: 15...const payment = await Sales.initializePayment(orderNumber, paymentProvider.paymentMethodID);Sales.initializePayment()
will return a token in parameter1. This token is used to initialize and render the Braintree’s Drop-in UI. The Braintree's Drop-in is a customizable payment UI solution from Braintree. It allows you to easily integrate multiple payment methods, such as credit cards and PayPal, without building a UI from scratch....import Sales from '@arc-publishing/sdk-sales';import DropIn from 'braintree-web-drop-in';...export const BraintreeCheckout = props => {const [error, setError] = useState(null);const [isSubmitting, setIsSubmitting] = useState(false);useEffect(() => {const initPayment = async () => {try {const payment = await Sales.initializePayment(orderNumber, paymentMethodID);var button = document.querySelector('#submit-button');DropIn.create({authorization: payment.parameter1,container: '#dropin-container',card: {cardholderName: {required: true}},paypal: {flow: 'vault'}},(_createErr, instance) => {button.addEventListener('click', () => {instance.requestPaymentMethod((err, payload) => {setIsSubmitting(true);if (payload && payload.nonce) {// If you need to pass reCAPTCHA// Sales.finalizePayment(orderNumber, paymentMethodID, payload.nonce, null, captcha)Sales.finalizePayment(orderNumber, paymentMethodID, payload.nonce).then(() => {setIsSubmitting(false);// Then, direct the user to a success page}).catch(err => {setIsSubmitting(false);if (err && err.message) {setError(err.message);}});} else {setIsSubmitting(false);if (err && err.message) {setError(err.message);}}});});});} catch (err) {if (err && err.message) {setError(err.message);}}};initPayment();}, [orderNumber, paymentMethodID]);return (<>{error && <p> error: {error}</p>}<div id="dropin-container"></div><button id="submit-button" className="button is-primary is-fullwidth" disabled={isSubmitting}>Purchase {isSubmitting && <i className="fas fa-spinner fa-pulse fa-lg"></i>}</button></>);} -
Finalize payment
: In the previous code, you can see that oncepayload.nonce
is detected, we callSales.finalizePayment()
along with the order number and the reCAPTCHA token (if this feature is enabled for checkout).