← Back to Blake
AgentBlake
PayPal and Braintree integration
Connects server-controlled orders, captures and subscription events to a coherent payment and dispute lifecycle.
paypal-braintree-integration
See how it helpsWhen is it useful?
Use when implementing PayPal checkout or Braintree recurring billing.
What does it help you do?
- Separates server order creation, buyer approval and server capture.
- Maps subscription events to actual entitlements and billing states.
- Verifies webhooks and tracks refunds or disputes explicitly.
Try asking this
Implement PayPal checkout in a sandbox and handle buyer approval followed by an uncertain capture response.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
PayPal & Braintree Integration
PayPal and Braintree flows require strict separation between client-side approval and server-side authorization/capture. Never treat a client-side onApprove callback alone as a completed payment.
1. PayPal Orders v2 (One-Time Checkout)
Follow the authoritative two-step server-orchestrated flow:
- Create Order on Server (
POST /v2/checkout/orders):- Client requests checkout for a server-known item/plan.
- Server computes
amount(currency_code+ stringvalueformatted to the currency's exact decimal support, e.g.,"29.99"for USD/EUR, or integer string"5000"forHUFandJPY— PayPal rejects decimals for HUF!), setsintent: "CAPTURE", attachescustom_id/invoice_id(for deduplication), and returns the PayPalorderID.
- Buyer Approves in PayPal JS SDK:
- The buyer approves the order in the PayPal button modal/redirect, triggering client
onApprove({ orderID }).
- The buyer approves the order in the PayPal button modal/redirect, triggering client
- Capture Order on Server (
POST /v2/checkout/orders/{id}/capture):- Client calls your backend with
orderID; your backend calls PayPal's capture endpoint with aPayPal-Request-Ididempotency header. - Inspect
purchase_units[0].payments.captures[0].status:COMPLETED: payment settled; record capture ID and grant entitlement.PENDING: reviewstatus_details.reason(e.g.,ECHECK, regulatory review); keep local paymentprocessinguntil webhook confirms completion.DECLINED/FAILED(orINSTRUMENT_DECLINEDerror): return recoverable error so the client SDK can callactions.restart()to pick another funding source.
- Client calls your backend with
2. PayPal Subscriptions & Braintree Recurring Billing
- PayPal Subscriptions (
/v1/billing/subscriptions):- Link Product -> Billing Plan -> Subscription (
custom_idset to your internal tenant/user ID). - Track lifecycle via webhooks:
BILLING.SUBSCRIPTION.ACTIVATED,PAYMENT.SALE.COMPLETED(actual recurring payment settlement),BILLING.SUBSCRIPTION.PAYMENT.FAILED,BILLING.SUBSCRIPTION.SUSPENDEDandBILLING.SUBSCRIPTION.CANCELLED. - Note that
BILLING.SUBSCRIPTION.CREATEDor client approval does not mean the first payment settled — verify subscription status andPAYMENT.SALE.COMPLETED.
- Link Product -> Billing Plan -> Subscription (
- Braintree (Hosted Fields / Drop-in):
- Generate
clientTokenon the server; client exchanges payment details for a single-usepaymentMethodNonce. - Pass
paymentMethodNonceand 3DS verification data togateway.transaction.sale()orgateway.subscription.create()on the server. - Distinguish
authorizedvs.submitted_for_settlementvs.settledvs.settlement_declined.
- Generate
3. Webhook Verification & Dispute Lifecycle
- PayPal Webhook Verification: verify incoming webhooks by calling
POST /v1/notifications/verify-webhook-signature(passingtransmission_id,transmission_time,cert_url,auth_algo,transmission_sig,webhook_idand the raw event) or cryptographic certificate verification, and deduplicate byevent.id. - Braintree Webhook Parsing: use
gateway.webhookNotification.parse(bt_signature, bt_payload)and deduplicate by notification timestamp + kind + subject ID. - Refunds & Disputes: handle
PAYMENT.CAPTURE.REFUNDED,PAYMENT.CAPTURE.REVERSEDandCUSTOMER.DISPUTE.CREATED/RESOLVEDto freeze or adjust entitlements and record audit ledger entries.
Included files 1
SKILL.md
