PayPal Payments

PayPal Payments

This guide walks through the full PayPal payment lifecycle — from creating an order to post-payment operations like refunds and voids.


1. Create a PayPal Order

Send a POST request to /v1/paypal/orders to initiate a PayPal payment session.

BR-DGE returns an orderId and a redirectUrl — use the redirectUrl to send your customer to PayPal to log in and approve the payment.

Request

{
  "amount": 1001,
  "currencyCode": "GBP",
  "displayName": "Brand Name",
  "intent": "capture",
  "customerOrderCode": "ABC123",
  "locale": "en-US",
  "invoiceId": "{{$guid}}",
  "enableShippingAddress": true,
  "shippingAddressEditable": false,
  "returnUrl": "https://www.example.com/return",
  "cancelUrl": "https://www.example.com/cancel",
  "shippingAddressOverride": {
    "address1": "Line 1",
    "address2": "Line 2",
    "town": "Edinburgh",
    "county": "State",
    "postcode": "EH10 8E1",
    "country": "GB",
    "phoneNumber": "4084396009",
    "recipientName": "John Doe",
    "buildingNumberOrName": "20"
  },
  "lineItems": [
    {
      "name": "T-Shirt",
      "description": "Blue T-Shirt",
      "quantity": 1,
      "unitAmount": 1000,
      "unitTax": 1
    }
  ],
  "customer": {
    "accountId": "GR9MNXKHQTBY8",
    "firstName": "John",
    "lastName": "Doe",
    "email": "[email protected]",
    "phoneNumber": "4084396009",
    "country": "GB",
    "creationTimestamp": "2024-12-09T19:14:55.277-0:00"
  }
}

Key Request Fields

FieldRequiredDescription
amountPayment amount in minor units (e.g. pence for GBP)
currencyCodeISO 4217 currency code (e.g. GBP)
displayNameYour brand name as shown to the customer on PayPal
intentcapture to settle immediately; authorize to reserve funds for later capture
customerOrderCodeYour internal order reference
localeCustomer locale (e.g. en-US)
invoiceIdUnique invoice identifier for this transaction
returnUrlWhere to redirect the customer after PayPal approval
cancelUrlWhere to redirect the customer if they cancel on PayPal
shippingAddressOverrideOptionalPre-filled shipping address shown to the customer
lineItemsOptionalItemised breakdown of the order
customerRecommendedCustomer data used by PayPal for risk analysis
📘

Improve Approval Rates

Including the customer object is strongly recommended. This data is used by PayPal for risk analysis and can reduce the likelihood of payment friction or declines.

Response

{
  "code": "1000",
  "message": "Order Created",
  "id": "691b0cf0252154ac56383ce42fdddb10",
  "orderId": "2NF630639H718704B",
  "redirectUrl": "https://www.sandbox.paypal.com/checkoutnow?token=2NF630639H718704B",
  "intent": "capture",
  "status": "CREATED",
  "creationTimestamp": "2025-01-01T10:00:00Z"
}

Redirect the customer to the redirectUrl to complete PayPal approval. Additionally, you can leverage the PayPal JavaScript SDK to manage the frontend payment flow. Check out our guide for integrating this SDK into your payment page.


2. Customer Approves the Payment

After the customer logs in and approves the payment on PayPal, the onApprove() event is triggered on your frontend. At this point, notify your server and proceed to authorize or capture the order.


3. Authorize or Capture

Send a POST request to /v1/paypal/orders/{orderId}/payments using the orderId from the create order response.

The behaviour depends on the intent set when you created the order.


Capture (Immediate Settlement)

Funds are taken from the customer immediately upon approval.

Response

{
  "code": "1000",
  "message": "Approved",
  "id": "691b0cf0252154ac56383ce42fdddb10",
  "paymentId": "1aa76e6a-15ba-4f46-a6e7-3080aba5a229",
  "orderId": "2NF630639H718704B",
  "status": "COMPLETED",
  "amount": 1001
}

Authorize (Reserve Funds)

Funds are reserved on the customer's account but not yet settled. You can capture them later.

Response

{
  "code": "1000",
  "message": "Approved",
  "id": "691b0cf0252154ac56383ce42fdddb10",
  "paymentId": "1aa76e6a-15ba-4f46-a6e7-3080aba5a229",
  "orderId": "2NF630639H718704B",
  "status": "CREATED",
  "amount": 1001
}
📘

Save the paymentId

Store the paymentId from the authorization response. You'll need it to perform a delayed capture, refund, or void.


Delayed Capture

To settle an authorized payment, send a POST to /v1/payments/{paymentId}/capture.

Response

{
  "code": "1000",
  "message": "Approved",
  "id": "...",
  "psp": {
    "name": "PayPal-Direct"
  }
}

4. Retrieve a PayPal Order

Check the status of a PayPal order at any time by sending a GET request to /v1/paypal/orders/{orderId}.

Response

{
  "id": "691b0cf0252154ac56383ce42fdddb10",
  "orderId": "2NF630639H718704B",
  "intent": "capture",
  "status": "COMPLETED",
  "creationTimestamp": "2025-01-01T10:00:00Z",
  "psp": {
    "additionalInfo": {
      "paymentSource": {
        "name": "John Doe",
        "email": "[email protected]",
        "accountId": "BYENZRGXD228J"
      },
      "purchaseUnits": [
        {
          "referenceId": "default",
          "description": "Blue T-Shirt",
          "invoiceId": "abc-123",
          "currencyCode": "GBP",
          "unitAmount": 1000,
          "unitTax": 1
        }
      ]
    }
  }
}

Order Status Values

StatusDescription
CREATEDOrder has been created and is awaiting customer action
PAYER_ACTION_REQUIREDCustomer action is required to proceed
APPROVEDCustomer has approved the payment on PayPal
COMPLETEDPayment has been authorized, captured, or declined

5. Refund a Payment

Send a POST to /v1/payments/{paymentId}/refund to return funds to the customer.

Response

{
  "code": "1000",
  "message": "Approved",
  "id": "...",
  "psp": {
    "name": "PayPal-Direct",
    "transactionId": "6EW22835YU8376810"
  }
}

6. Void an Authorisation

To cancel a reserved authorization before it is captured, send a POST to /v1/payments/{paymentId}/void.

Response

{
  "code": "1000",
  "message": "Approved",
  "id": "...",
  "psp": {
    "name": "PayPal-Direct",
    "transactionId": "6EW22835YU8376810"
  }
}
🚧

Authorized Payments Only

You can only void a payment that has been authorized but not yet captured. Already-captured payments cannot be voided — use a refund instead.