One-time payments

You can set up one-time payments to process a buyer’s single-immediate payment through PayPal without storing the payment method for future use.

This guide explains how to use the Braintree GraphQL APIs to integrate PayPal one-time payments into your application. Use this integration for infrequent payments with high Average Order Value (AOV), typically physical-goods purchases.

For information on how to set up the checkout-with-vault flow to process one-time payments and store the buyer’s payment method, see Create PayPal one-time payment under Checkout-with-vault.

WorkflowAnchorIcon

The following diagram illustrates the process to create PayPal one-time payments flow.

1. Create transaction risk contextAnchorIcon

Use the createTransactionRiskContext mutation to pass supplementary risk-related data to PayPal and to create a transaction risk context that supports risk management. On success, PayPal returns two values — save both for use in later steps:
Return Value
clientMetadataId Pass as riskData.deviceData.correlation_id in chargePaymentMethod.
paypalRiskCorrelationId Step 2 (client-side) and Step 3 — pass in createPayPalOneTimePayment.
GraphQl Mutation
  1. Mutation
mutation ($input: CreateTransactionRiskContextInput!) {
  createTransactionRiskContext(input: $input) {
    clientMetadataId
    paypalRiskCorrelationId
  }
}
Variables
  1. Variables
{
  "input": {
    "riskContext": {
      "fields": [
        { "name": "sender_account_id", "value": "xyz123" },
        { "name": "txn_count_total", "value": "15987" }
      ]
    }
  }
}
Response
  1. Response
{
  "data": {
    "createTransactionRiskContext": {
      "clientMetadataId": "01e59aa07d2187e13b1bf9cf42a45596",
      "paypalRiskCorrelationId": "01e59aa07d2187e13b1bf9cf42a45596"
    }
  }
}

2. Configure client-side SDK with risk correlation IDAnchorIcon

Choose between Data Collector integration for the full page redirect and In-Context PayPal button flow integration for PayPal modal or popup experience
Data collectorAnchorIcon
To initialize device fingerprinting and associate it with your risk context before the PayPal redirect and the full page redirect, use Initialize Data Collector with Risk Correlation ID
braintree.dataCollector.create({
  client: clientInstance,
  riskCorrelationId: paypalRiskCorrelationId, // From Step 1
  paypal: true,
}, function (err, dataCollectorInstance) {
  if (err) {
    // Handle error in creation of data collector
    return;
  }
  // At this point, you should access the dataCollectorInstance.deviceData value
  // and provide it to your server, e.g. by injecting it into your form as a hidden input.
  var deviceData = dataCollectorInstance.deviceData;
  console.log("DEVICE DATA: " + deviceData);
});
In-Context PayPal Button FlowAnchorIcon

To create an in-context PayPal experience with the risk correlation ID embedded in the payment creation, then automatically tokenizes the payment after approval, and to use the PayPal modal or pop-up experience:

Initialize the Braintree Client SDK and PayPal Checkout
braintree.client.create({
  authorization: CLIENT_AUTHORIZATION
}, function (clientErr, clientInstance) {
  // Stop if there was a problem creating the client
  if (clientErr) {
    console.error('Error creating client:', clientErr);
    return;
  }
  // Create a PayPal Checkout component
  braintree.paypalCheckout.create({
    client: clientInstance
  }, function (paypalCheckoutErr, paypalCheckoutInstance) {
    if (paypalCheckoutErr) {
      console.error('Error creating PayPal Checkout:', paypalCheckoutErr);
      return;
    }
    paypalCheckoutInstance.loadPayPalSDK({
      currency: 'USD',
      intent: 'capture'
    }, function () {
      paypal.Buttons({
        fundingSource: paypal.FUNDING.PAYPAL,
        createOrder: function () {
          return paypalCheckoutInstance.createPayment({
            flow: 'checkout', // Required
            amount: '15.00', // Required
            riskCorrelationId: paypalRiskCorrelationId, // From Step 1
            currency: 'USD', // Required, must match loadPayPalSDK
            intent: 'capture' // Must match loadPayPalSDK
          });
        },
        onApprove: function (data, actions) {
          return paypalCheckoutInstance.tokenizePayment(data, function (err, payload) {
            if (err) {
              console.error('Tokenization error:', err);
              return;
            }
            // Submit payload.nonce to your server for charging (Step 6)
            submitNonceToServer(payload.nonce);
          });
        }
      }).render('#paypal-button');
    });
  });
});

3. Create a PayPal one-time payment (with risk correlation ID)AnchorIcon

If you choose to use Full Page Redirect flow, use the createPayPalOneTimePayment mutation to initiate a PayPal One-time payment. Pass the following input fields and their values:
FieldDescription
paypalRiskCorrelationIdThe risk correlation ID returned from Step 1. This is required for STC integration.
returnUrlThe URL to redirect the payer after authentication. Must use an approved HTTPS hostname.
cancelUrlThe URL to redirect the payer if they cancel. Must be HTTPS.
payerEmailThe buyer's email address (buyer identifier).
lineItemsItems purchased. Shown to the buyer in post-purchase emails and their PayPal Activity.
shippingAddressOptional. Pass shipping details to be eligible for PayPal Seller Protection.
shippingOptionsOptional. List of shipping options offered to the payer.
recipientEmailOptional. Email address of the digital goods recipient (gift cards, movies, software).
GraphQl Mutation
  1. Mutation
mutation ($input: CreatePayPalOneTimePaymentInput!) {
  createPayPalOneTimePayment(input: $input) {
    approvalUrl
    paymentId
  }
}
Variables
  1. Variables
{
  "input": {
    "merchantAccountId": "merchant_account_id",
    "amount": {
      "value": "15.00",
      "currencyCode": "USD"
    },
    "returnUrl": "https://merchant_domain_name/paypal/returnURL",
    "cancelUrl": "https://merchant_domain_name/paypal/cancelURL",
    "intent": "SALE",
    "lineItems": [
      {
        "name": "Test Customer",
        "quantity": 1,
        "unitAmount": "13.00",
        "type": "DEBIT",
        "description": "Authentic",
        "productCode": "12345",
        "unitTaxAmount": "2.00",
        "url": "https://example.com",
        "imageUrl": "https://example.com/products/12345.png",
        "upc": {
          "upcType": "UPC_A",
          "upcCode": "042100012345"
        }
      }
    ],
    "paypalRiskCorrelationId": "01e59aa07d2187e13b1bf9cf42a45596",
    "paypalExperienceProfile": {
      "collectShippingAddress": true,
      "shippingAddressEditable": true,
      "brandName": "Empire Co.",
      "landingPageType": "DEFAULT",
      "locale": "en-US",
      "userAction": "COMMIT"
    }
  }
}
Response
  1. Response
{
    "data": {
        "createPayPalOneTimePayment": {
            "approvalUrl": "https://www.paypal.com/checkoutnow?token=5A273719CB6355913",
            "paymentId": "5A273719CB6355913"
        }
    }
}

4. Send payers to PayPal to approve paymentAnchorIcon

In Full Page Redirect flow, send the approvalUrl returned from createPayPalOneTimePayment to your client-side code. Include logic to redirect the payer to the PayPal site where they can approve the payment. After the payer approves the payment on the PayPal site:
  • Payers are redirected back to yourreturnUrl.
  • The payment ID,payer ID, and payment tokenvalues are appended as query string parameters to the return URL.

5. Tokenize and charge payment methodAnchorIcon

In Full Page Redirect flow, use the tokenizePayPalOneTimePayment mutation to convert the payment into a tokenized payment method. Pass the payment ID and payer ID values received as query string parameters in the return URL. GraphQl Mutation
  1. Mutation
mutation ($input: TokenizePayPalOneTimePaymentInput!) {
  tokenizePayPalOneTimePayment(input: $input) {
    paymentMethod {
      id
    }
  }
Variables
  1. Variables
{
  "input": {
    "merchantAccountId": "merchant_account_id",
    "paypalOneTimePayment": {
      "payerId": "VGRS82V5P2RFY",
      "paymentId": "5A273719CB6355913"
    }
  }
}
Response
  1. Response
{
    "data": {
        "tokenizePayPalOneTimePayment": {
            "paymentMethod": {
                "id": "e8fcbb1f-189e-1642-0414-ce136b58a411"
            }
        }
    }
}

6. Charge Payment MethodAnchorIcon

Use the chargePaymentMethod mutation to capture the payment and receive the transaction details. This applies to both the Full Page Redirect flow and the In-Context Button flow. GraphQL Mutation
  1. Mutation
mutation ($input: ChargePaymentMethodInput!) {
  chargePaymentMethod(input: $input) {
    transaction {
      id
      status
    }
  }
}
Variables
  1. Variables
{
  "input": {
    "paymentMethodId": "e8fcbb1f-189e-1642-0414-ce136b58a411",
    "transaction": {
      "amount": "15.00",
      "merchantAccountId": "merchant_account_id",
      "riskData": {
        "deviceData": "{\"correlation_id\": \"01e59aa07d2187e13b1bf9cf42a45596\"}"
      }
    }
  }
}