Skip to main content
POST
/
api
/
v1
/
payments
/
checkout
/
order
/
{id}
Process Payment
curl --request POST \
  --url https://api.example.com/api/v1/payments/checkout/order/{id}/ \
  --header 'Content-Type: application/json' \
  --data '
{
  "payment_method_nonce": "<string>"
}
'
{
  "success": "Payment was successful"
}

Overview

This endpoint processes payment for an order using the Braintree payment gateway. It accepts a payment method nonce from the client, processes the transaction, and updates the order status accordingly.
Orders can only be paid once. Attempting to pay an already paid order will result in a 400 error.

Authentication

This endpoint requires authentication. Include a valid authentication token in the request headers.
Authorization: Bearer <your_token>

Path Parameters

id
string
required
The UUID of the order to process payment for. Must belong to the authenticated customer.

Request Body

payment_method_nonce
string
required
The payment method nonce generated by Braintree on the client side. This nonce represents the customer’s payment information and is obtained from the Braintree Drop-in UI or hosted fields.

Example Request

{
  "payment_method_nonce": "fake-valid-nonce"
}

Response

{
  "success": "Payment was successful"
}

Payment Processing Flow

When a payment is submitted, the following steps occur:
  1. Validation: Checks if order status is not already “paid”
  2. Transaction Record: Creates a transaction record with “pending” status
  3. Customer Data: Prepares customer and shipping information from the order
  4. Gateway Request: Submits transaction to Braintree with:
    • Payment amount
    • Payment method nonce
    • Shipping address
    • Auto-settlement enabled
    • Vault storage for payment method
  5. Success Handling: If payment succeeds:
    • Order status updated to “paid”
    • Transaction status updated to “successful”
    • Confirmation email sent (async)
    • Transaction exported to CSV (async)
    • Product stock updated (async)
  6. Failure Handling: If payment fails:
    • Transaction status updated to “failed”
    • Error message returned to client

Post-Payment Tasks

After successful payment, the following async tasks are triggered:
An email confirmation is sent to the customer with order details and payment receipt.Task: send_order_confirmation_email.delay(order)
Transaction details are written to a CSV file for record-keeping.Task: write_trxn_to_csv.delay(order, customer, transaction_id)
Product inventory is decremented based on order items.Task: update_stock.delay(order, customer)

Testing with Braintree

When testing in the Sandbox environment, use the following test card details:

Valid Card

Number: 5555 5555 5555 4444Expiration: Any future date (e.g., 02/26)CVV: Any 3 digitsResult: Payment succeeds

Processor Declined

Number: 4000 1111 1111 1115Expiration: Any future dateResult: Payment declined by processor
For a complete list of test cards and scenarios, see the Braintree Testing Guide.

Transaction Status

Each payment attempt creates a transaction record with one of the following statuses:
  • pending: Transaction initiated, awaiting gateway response
  • successful: Payment processed successfully
  • failed: Payment was declined or encountered an error
  • refunded: Payment was refunded (managed separately)

Error Responses

400 Bad Request
error
Returned when:
  • Order is already paid
  • Payment method nonce is missing
401 Unauthorized
error
Returned when authentication credentials are not provided or invalid
404 Not Found
error
Returned when:
  • Order ID doesn’t exist
  • Order doesn’t belong to the authenticated customer
502 Bad Gateway
error
Returned when payment processing fails at the Braintree gateway. The error message includes details from Braintree about why the transaction was declined.

Braintree Configuration

The payment gateway is configured in config/settings.py using environment variables:
BRAINTREE_CONF = braintree.Configuration(
    braintree.Environment.Sandbox,
    merchant_id=BRAINTREE_MERCHANT_ID,
    public_key=BRAINTREE_PUBLIC_KEY,
    private_key=BRAINTREE_PRIVATE_KEY
)
The API uses Braintree’s Sandbox environment for testing. For production, update the environment to braintree.Environment.Production.

Customer Data Submitted

The following customer data is sent to Braintree with the transaction:
{
  "first_name": "John",
  "last_name": "Doe",
  "street_address": "123 Main St",
  "postal_code": "12345",
  "locality": "New York",
  "region": "NY",
  "country_name": "United States"
}
This data is prepared from the order’s billing address using the _prepare_customer_data method.

Gateway Options

The transaction is submitted to Braintree with the following options:
submit_for_settlement
boolean
default:"true"
Automatically submits the transaction for settlement rather than just authorizing it.
store_in_vault_on_success
boolean
default:"true"
Saves the payment method to the Braintree Vault for future use (allows for one-click checkout on future orders).

Code Reference

Implementation: payments/views.py:56 Helper methods:
  • _prepare_customer_data: payments/views.py:41
  • _post_payment_tasks: payments/views.py:36

Build docs developers (and LLMs) love