kuriousagency / commerce-braintree
Braintree gateway for Craft Commerce
Package info
github.com/webdna/commerce-braintree
Type:craft-plugin
pkg:composer/kuriousagency/commerce-braintree
Requires
- braintree/braintree_php: ^6.9
- craftcms/cms: ^4.0.0||^5.0
- craftcms/commerce: ^4.0||^5.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-master
- 3.2.0
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0-beta.11
- 3.0.0-beta.10
- 3.0.0-beta.9
- 3.0.0-beta.8
- 3.0.0-beta.7
- 3.0.0-beta.6
- 3.0.0-beta.5
- 3.0.0-beta.4
- 3.0.0-beta.3
- 3.0.0-beta.2
- 3.0.0-beta.1
- 2.4.3
- 2.4.1
- 2.4.0
- 2.3.9
- 2.3.8
- 2.3.7
- 2.3.6
- 2.3.5
- 2.3.4
- 2.3.3
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.18
- 2.1.17
- 2.1.16
- 2.1.15
- 2.1.14
- 2.1.13
- 2.1.12
- 2.1.11
- 2.1.10
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.2
- 2.0.1
- 2.0.0
- 1.0.3
- 1.0.2
This package is auto-updated.
Last update: 2026-10-20 17:27:49 UTC
README
Braintree for Craft Commerce
This plugin provides a Braintree integration for Craft Commerce.
Features
- Merchant Accounts: supports Braintree's merchant accounts for multiple payment currencies.
- Subscriptions: support subscription integration.
- Payment sources: customers can save a card or PayPal account, subscribe with it and pay orders with it.
- DropinUi: Braintree's dropinUi is the default for
getPaymentFromHTML()method. - Supports 3DSecure 2.
- Supports Paypal, Apple Pay & Google Pay.
- Vault: Supports Braintree's vault for securely storing payment details.
Requirements
This plugin requires Craft Commerce 4.0 or later.
Installation
You can install this plugin from the Plugin Store or with Composer.
From the Plugin Store
Go to the Plugin Store in your project’s Control Panel and search for Braintree for Craft Commerce”. Then click on the “Install” button in its modal window.
With Composer
Open your terminal and run the following commands:
# go to the project directory cd /path/to/my-project.test # tell Composer to load the plugin composer require webdna/commerce-braintree # tell Craft to install the plugin ./craft plugin/install commerce-braintree
Setup
To add the Braintree payment gateway, go to Commerce → Settings → Gateways, create a new gateway, and set the gateway type to “Braintree”.
Payment security enforcement
This plugin does not allow submitting credit card details directly to Braintree gateway. Instead, you must tokenize the card before submitting the payment form. Calling the default getPaymentFormHtml() method on the gateway will automatically use Braintree's DropinUI interface and tokenize the payment details. If you wish to have control over the dropinUi options or would prefer to use Braintree's HostedFields instead, you will need to manually add the fields and javascript instead of using the default method.
3D secure payments
To allow 3D Secure payments, you must enable it in your Braintree account, then pass in the optional parameter into the getPaymentFormHtml() method. Default: false
gateway.getPaymentFormHtml({threeDSecure:true})
Options
These are options that can be passed into the default getPaymentFormHtml() method.
Store Name
This will set the store name for paypal, google pay & apple pay. Default: siteName
gateway.getPaymentFormHtml({storeName:'My WebSite'})
Translations
This will allow the setting of the dropinUi translations: Examples
gateway.getPaymentFormHtml({translations:{chooseAWayToPay:'Choose a way to pay'}})
Vault
This allows the payment details to be store in Braintree's Vault, not the website. The DropinUi will display all saved payment methods. Default: false
gateway.getPaymentFormHtml({vault:true})
If you would like to allow the management of vaulted payment methods, then pass in the manage option. Default: false
gateway.getPaymentFormHtml({manage:true})
Drop-in options
Any of Braintree's drop-in create() options can be passed as dropinOptions. They are merged over the options the plugin sets, so you only need to give the parts you want to change:
- objects are merged key by key, so the plugin's other settings at the same level are kept;
- a string, number, boolean or array replaces the plugin's value;
nullremoves the option, e.g.paypal: nullhides PayPal.
authorization and container are always set by the plugin. Options are passed as JSON, so they cannot contain JavaScript functions.
{{ gateway.getPaymentFormHtml({
dropinOptions: {
card: {
overrides: {
fields: {
cvv: { placeholder: '' },
},
},
},
paypal: null,
paymentOptionPriority: ['card', 'googlePay', 'applePay'],
},
})|raw }}
This example removes the CVV placeholder dots (so an autofilled card without a CVV no longer looks complete), hides PayPal and orders the remaining payment methods. Field overrides lists what each card field accepts.
Payment sources
A payment source is a card or PayPal account saved in Braintree's vault against the customer, and listed in Commerce as, for example, "Visa ending in ••••1111" or "PayPal (buyer@example.com)". The Braintree customer's id is the Craft user's uid; it is created the first time it is needed. Deleting a payment source in Commerce deletes it from Braintree too.
Pass paymentSource: true to getPaymentFormHtml() for a form that saves a payment source. The drop-in then offers a card or PayPal (in PayPal's vault flow) and no Apple Pay or Google Pay, which need an amount and cannot be saved from the drop-in. subscription: true does the same.
Output the drop-in with |raw, namespace its fields with Commerce's commercePaymentFormNamespace filter, and give the form a <button type="submit">, which the drop-in enables once a payment method is entered.
Saving a payment source
The customer must be signed in.
{% requireLogin %}
{% set gateway = craft.commerce.gateways.getGatewayByHandle('braintree') %}
<form method="post">
{{ csrfInput() }}
{{ actionInput('commerce/payment-sources/add') }}
{{ hiddenInput('gatewayId', gateway.id) }}
{{ redirectInput('account/payment-methods') }}
{% namespace gateway.handle|commercePaymentFormNamespace %}
{{ gateway.getPaymentFormHtml({paymentSource: true})|raw }}
{% endnamespace %}
<label>
<input type="checkbox" name="isPrimaryPaymentSource" value="1">
Use this for my subscriptions
</label>
<button type="submit">Save</button>
</form>
A refusal from Braintree (a declined card, for example) comes back as "Could not create the payment source." with Braintree's message.
Listing and deleting the customer's saved sources uses Commerce's own actions:
{% for source in craft.commerce.paymentSources.getAllGatewayPaymentSourcesByCustomerId(gateway.id, currentUser.id) %}
<form method="post">
{{ csrfInput() }}
{{ actionInput('commerce/payment-sources/delete') }}
{{ hiddenInput('id', source.id) }}
{{ source.description }}
<button type="submit">Delete</button>
</form>
{% endfor %}
commerce/payment-sources/set-primary-payment-source, posted with the source's id, makes it the one subscriptions use.
Verifying cards when they are saved
Turn on Verify cards when saved? in the gateway's settings to have Braintree verify a card before it is saved, so a card the bank declines is refused on the form ("Do Not Honor", for example) instead of failing at its first charge. Braintree makes a small authorisation and voids it. PayPal accounts are not affected. The setting is off by default and takes an environment variable.
The verification runs against the merchant account of the store's primary currency and is subject to your Braintree account's address (AVS) and CVV rules. The customer's primary billing address is sent with it when they have one. If your rules require a street address, a customer with no primary billing address cannot save a card and sees "Street address is required.", so ask for an address before the card on those accounts.
Paying with a saved payment source
Post the source's id as paymentSourceId to commerce/payments/pay. The order is charged to the saved card or PayPal account; no drop-in is needed.
<form method="post"> {{ csrfInput() }} {{ actionInput('commerce/payments/pay') }} {{ redirectInput('shop/customer/order?number={number}') }} {% for source in craft.commerce.paymentSources.getAllPaymentSourcesByCustomerId(currentUser.id) %} <label> <input type="radio" name="paymentSourceId" value="{{ source.id }}" {{ loop.first ? 'checked' }}> {{ source.description }} </label> {% endfor %} <button type="submit">Pay</button> </form>
A checkout that posts the drop-in's fields, as before, is charged exactly as it always was, and saves no payment source.
Subscriptions
Creating a subscription plan
- To create a subscription plan, it must first be created within your Braintree account.
- Go to Commerce → Settings → Subscription plans and create a new subscription plan.
Subscribing
A subscription is charged to a saved payment source: the customer's primary one if it is on this gateway, otherwise the one they saved most recently. A customer with no saved source enters one in the drop-in on the subscribe form, and Commerce saves it before the subscription starts. Show the drop-in only to customers with nothing saved, so that the others subscribe with their primary source without re-entering it.
{% requireLogin %}
{% set plan = craft.commerce.plans.getPlanByHandle('monthly') %}
{% set gateway = plan.getGateway() %}
{% set sources = craft.commerce.paymentSources.getAllGatewayPaymentSourcesByCustomerId(gateway.id, currentUser.id) %}
<form method="post">
{{ csrfInput() }}
{{ actionInput('commerce/subscriptions/subscribe') }}
{{ hiddenInput('planUid', plan.uid|hash) }}
{{ redirectInput('account/subscriptions') }}
{% if sources is empty %}
{% namespace gateway.handle|commercePaymentFormNamespace %}
{{ gateway.getPaymentFormHtml({subscription: true})|raw }}
{% endnamespace %}
{% endif %}
<button type="submit">Subscribe</button>
</form>
With no saved source and no drop-in fields posted, subscribing fails with "No payment sources are saved to use for subscriptions."
Changing a subscription's payment method
commerce-braintree/subscriptions/update-payment takes subscriptionUid and planUid (both hashed) with the drop-in's fields, not namespaced ({{ gateway.getPaymentFormHtml({subscription: true})|raw }} straight into the form), and must be posted by the subscription's own customer. commerce-braintree/payment-methods/delete takes the gateway's gateway handle and a vaulted method's token, and deletes it only when it belongs to the signed-in customer. Both accept POST requests only.
Options when subscribing
Trial Days
Trial days are setup as part of the plan within Braintree.
Options when switching between different subscription plans
The prorate parameter
If this parameter is set to true, the subscription switch will be prorated.