Braintree Integration
Advanced Guide - prior knowledge required
In order to follow this guide properly, we recommend that you get familiar with the payment flow and payment API concepts first.
This guide shows how to integrate Braintree Credit Card payments using the Shopware Braintree App in a headless frontend.
Prerequisites
- Shopware 6 instance with the Braintree App installed and configured
- Braintree payment method enabled in your sales channel
- Customer account with valid billing/shipping address
Install dependencies
npm install braintree-web-drop-inIntegration Flow
The Braintree App integration requires three steps:
- Get a client token from Shopware's App System
- Initialize the Braintree Drop-in UI
- Create order and handle payment with the nonce
Step 1: Get Client Token
First, obtain an app token from Shopware, then exchange it for a Braintree client token.
const { apiClient } = useShopwareContext();
const { sessionContext } = useSessionContext();
// Get app token from Shopware Store-API
const tokenResponse = await apiClient.invoke(
"generateJWTAppSystemAppServer post /app-system/{name}/generate-token",
{ pathParams: { name: "SwagBraintreeApp" } },
);
const { token, shopId } = tokenResponse.data;
// Get Braintree client config from the app server
const currencyId = sessionContext.value?.currency?.id;
const salesChannelId = sessionContext.value?.salesChannel?.id;
const configResponse = await fetch(
`https://braintree.shopware.com/api/client/config?shop-id=${shopId}¤cy-id=${currencyId}&sales-channel-id=${salesChannelId}`,
{
method: "POST",
headers: {
"shopware-app-token": token,
"shopware-app-shop-id": shopId,
},
},
);
const { clientToken } = await configResponse.json();Important
Use the shopware-app-token header, NOT Authorization: Bearer. Using the wrong header format will result in 500 errors.
Step 2: Initialize Braintree Drop-in
import dropin from "braintree-web-drop-in";
const instance = await dropin.create({
authorization: clientToken,
container: "#dropin-container",
dataCollector: true, // Required for deviceData (fraud detection)
card: {
cardholderName: {
required: true,
},
},
});Step 3: Create Order and Handle Payment
When the user submits payment, get the nonce from the Drop-in, create the order, then call /handle-payment with the Braintree data.
const { createOrder } = useCheckout();
const { apiClient } = useShopwareContext();
async function onPaymentSubmit() {
// Get nonce from Braintree Drop-in
const { nonce, deviceData } = await instance.requestPaymentMethod();
// Create order (no braintree params here)
const order = await createOrder();
// Handle payment WITH Braintree data
await apiClient.invoke("handlePaymentMethod post /handle-payment", {
body: {
orderId: order.id,
finishUrl: `${window.location.origin}/checkout/finish`,
errorUrl: `${window.location.origin}/checkout/error`,
braintreeNonce: nonce,
braintreeDeviceData: deviceData,
},
});
}Important
Pass braintreeNonce and braintreeDeviceData to /handle-payment, NOT to /checkout/order.
Test Cards
For Braintree sandbox testing:
| Card Type | Number | Expiry | CVV |
|---|---|---|---|
| Visa | 4111 1111 1111 1111 | Any future | Any |
Working Example
See the complete working example in the Composable Frontends repository: