PayPal
===
### Integrate on your servers
#### Creating transactions
Once the customer has successfully authenticated with PayPal, include the [paymentMethodId](https://graphql.braintreepayments.com/guides/concepts/#the-lifecycle-of-a-payment) parameter in the [chargePayPalAccount](https://graphql.braintreepayments.com/reference/#Mutation--chargePayPalAccount) call on your server.
#### Using device data
If the PayPal transaction was initiated from a Vault record and is not a recurring transaction, [collect device data](https://developer.paypal.com/braintree/docs/guides/premium-fraud-management-tools/device-data-collection) from the client and include the collected client device data via the *deviceData* parameter inside *riskData*. Doing so will help reduce decline rates.
Below includes an example call with relevant PayPal parameters and device data:
<MutationCodeBlock>
{`mutation ChargePayPalAccount($input: ChargePayPalAccountInput!){
chargePayPalAccount(input: $input) {
transaction {
id
amount {
value
currencyCode
}
paymentMethodSnapshot {
...on PayPalTransactionDetails{
captureId
payerStatus
}
}
}
}
}`}
</MutationCodeBlock>
<VariablesCodeBlock>
{`{
"input": {
"paymentMethodId": "fake-paypal-one-time-nonce",
"transaction": {
"amount": "10.00",
"orderId": "orderId",
"riskData": {
"customerBrowser": "netscap_1.0",
"customerIp": "8.8.8.8",
"deviceData": "android_v15.0_z2"
},
"vaultPaymentMethodAfterTransacting": {
"when": "ON_SUCCESSFUL_TRANSACTION"
}
},
"options": {
"customField": "PayPal custom field",
"description": "Description for PayPal email reciept"
}
}
}`}
</VariablesCodeBlock>
<ResponseCodeBlock>
{`{
"data": {
"chargePayPalAccount": {
"transaction": {
"id": "dHJhbnNhY3Rpb25fbW1yM3NjcWY",
"amount": {
"value": "10.00",
"currencyCode": "USD"
},
"paymentMethodSnapshot": {
"captureId": "CAPTURE-b0156a96f070",
"payerStatus": "VERIFIED"
}
}
}
},
"extensions": {
"requestId": "48692bbb-67ad-4c87-9830-f20e630a2245"
}
}`}
</ResponseCodeBlock>
See the recurring transactions section below for more information on recurring transactions.
If you want to create a new payment method in the Vault upon a successful transaction, use the *vaultPaymentMethodAfterTransacting* option with value *ON_SUCCESSFUL_TRANSACTION*. If a *customerId* is not included, a new customer will be created. If you want to include a PayPal Billing Agreement with the vaulted payment method, use the [Checkout with Vault flow](https://developer.paypal.com/braintree/docs/guides/paypal/checkout-with-vault).
#### Currency support
The customer will be charged in the currency associated with the merchantAccountId passed in the [chargePayPalAccount](https://graphql.braintreepayments.com/reference/#Mutation--chargePayPalAccount) call. We support [all currencies that PayPal REST APIs support](https://developer.paypal.com/reference/currency-codes/#paypal-account-payments).
For details on accepting foreign currencies with PayPal, see our [PayPal account setup guide](https://developer.paypal.com/braintree/articles/guides/payment-methods/paypal/setup-guide#foreign-currencies).
#### Shipping addresses
If you’ve collected a shipping address, you will need to pass that along with the [chargePayPalAccount](https://graphql.braintreepayments.com/reference/#Mutation--chargePayPalAccount) call. For details on shipping address fields, see our [AddressInput object reference](https://graphql.braintreepayments.com/reference/#input_object--addressinput). PayPal validates the shipping address, so it must follow the [PayPal address conventions](https://developer.paypal.com/docs/api/payments/v1/#definition-shipping_address).
Below is an example call including shipping details:
<MutationCodeBlock>
{`mutation ChargePayPalAccount($input: ChargePayPalAccountInput!) {
chargePayPalAccount(input: $input) {
transaction {
id
amount {
value
currencyCode
}
paymentMethodSnapshot {
...on PayPalTransactionDetails{
captureId
payerStatus
}
}
shipping {
shippingAmount
shippingAddress {
addressLine1
addressLine2
adminArea1
adminArea2
postalCode
countryCode
}
}
}`}
</MutationCodeBlock>
<VariablesCodeBlock>
{`{
"input": {
"paymentMethodId": "fake-paypal-one-time-nonce",
"transaction": {
"amount": "10.00",
"orderId": "orderId",
"riskData": {
"customerBrowser": "netscap_1.0",
"customerIp": "8.8.8.8",
"deviceData": "android_v15.0_z2"
},
"vaultPaymentMethodAfterTransacting": {
"when": "ON_SUCCESSFUL_TRANSACTION"
},
"shipping": {
"shippingAmount": "2.00",
"shippingAddress": {
"addressLine1": "222 W Merchandise Mart Plaza",
"addressLine2": "STE 800",
"adminArea1": "IL",
"adminArea2": "Chicago",
"postalCode": "60654",
"countryCode": "USA"
}
}
},
"options": {
"customField": "PayPal custom field",
"description": "Description for PayPal email reciept"
}
}
}`}
</VariablesCodeBlock>
<ResponseCodeBlock>
{`{
"data": {
"chargePayPalAccount": {
"transaction": {
"id": "dHJhbnNhY3Rpb25fZ2NkODdtMmc",
"amount": {
"value": "10.00",
"currencyCode": "USD"
},
"paymentMethodSnapshot": {
"captureId": "CAPTURE-777329b115ce",
"payerStatus": "VERIFIED"
},
"shipping": {
"shippingAmount": "2.00",
"shippingAddress": {
"addressLine1": "222 W Merchandise Mart Plaza",
"addressLine2": "STE 800",
"adminArea1": "IL",
"adminArea2": "Chicago",
"postalCode": "60654",
"countryCode": "US"
}
}
}
}
},
"extensions": {
"requestId": "eb6f0aa3-9cdc-4ff5-bac3-1ccdda4ad496"
}
}`}
</ResponseCodeBlock>
#### Seller Protection
By passing a shipping address, you may also be eligible for [PayPal Seller Protection](https://www.paypal.com/us/webapps/mpp/security/seller-protection). You can check the status of Seller Protection as follows:
<MutationCodeBlock>
{`mutation ChargePayPalAccount($input: ChargePayPalAccountInput!){
chargePayPalAccount(input: $input) {
transaction {
id
amount {
value
currencyCode
}
paymentMethodSnapshot {
...on PayPalTransactionDetails{
captureId
payerStatus
sellerProtectionStatus
}
}
}
}
}`}
</MutationCodeBlock>
<VariablesCodeBlock>
{`{
"input": {
"paymentMethodId": "fake-paypal-one-time-nonce",
"transaction": {
"amount": "10.00",
"orderId": "orderId",
"riskData": {
"customerBrowser": "netscap_1.0",
"customerIp": "8.8.8.8",
"deviceData": "android_v15.0_z2"
},
"vaultPaymentMethodAfterTransacting": {
"when": "ON_SUCCESSFUL_TRANSACTION"
}
},
"options": {
"customField": "PayPal custom field",
"description": "Description for PayPal email reciept"
}
}
}`}
</VariablesCodeBlock>
<ResponseCodeBlock>
{`{
"data": {
"chargePayPalAccount": {
"transaction": {
"id": "dHJhbnNhY3Rpb25fMDNjcTVrcjg",
"amount": {
"value": "10.00",
"currencyCode": "USD"
},
"paymentMethodSnapshot": {
"captureId": "CAPTURE-b5f937f18cbf",
"payerStatus": "VERIFIED",
"sellerProtectionStatus": "ELIGIBLE"
}
}
}
},
"extensions": {
"requestId": "afdeb2cb-12f0-47be-8e83-d65b546d546d"
}
}`}
</ResponseCodeBlock>
### Settlement
Unlike most payment types that settle in batches, [we capture PayPal funds immediately when you submit each transaction for settlement](https://developer.paypal.com/braintree/articles/guides/payment-methods/paypal/processing#settlement).
#### Authorizing PayPal Purchases
In order to authorize a purchase on a PayPal account for a specified amount, use the [authorizePayPalAccount](https://graphql.braintreepayments.com/reference/#Mutation--authorizePayPalAccount) call. This can be useful when you need to complete a task before finalizing the transaction, like verifying you have the item in stock. An input very similar to [chargePayPalAccount](https://graphql.braintreepayments.com/reference/#Mutation--chargePayPalAccount) is used for this call.<MutationCodeBlock>
{`mutation AuthorizePayPalAccount($input: AuthorizePayPalAccountInput!){
authorizePayPalAccount(input: $input) {
transaction {
id
amount {
value
currencyCode
}
merchantAccountId
paymentMethodSnapshot {
...on PayPalTransactionDetails{
captureId
payerStatus
}
}
}
}
}`}
</MutationCodeBlock>
<VariablesCodeBlock>
{`{
"input": {
"paymentMethodId": "fake-paypal-one-time-nonce",
"transaction": {
"amount": "10.00",
"orderId": "orderId",
"riskData": {
"customerBrowser": "netscap_1.0",
"customerIp": "8.8.8.8",
"deviceData": "android_v15.0_z2"
},
"vaultPaymentMethodAfterTransacting": {
"when": "ON_SUCCESSFUL_TRANSACTION"
}
},
"options": {
"customField": "PayPal custom field",
"description": "Description for PayPal email reciept"
}
}
}`}
</VariablesCodeBlock>
<ResponseCodeBlock>
{`{
"data": {
"authorizePayPalAccount": {
"transaction": {
"id": "dHJhbnNhY3Rpb25fazA4a3QyZDc",
"amount": {
"value": "10.00",
"currencyCode": "USD"
},
"merchantAccountId": "braintree",
"paymentMethodSnapshot": {
"captureId": null,
"payerStatus": "VERIFIED"
}
}
}
},
"extensions": {
"requestId": "3f7462ed-0ac5-4afc-a199-a7b5663e11a3"
}
}`}
</ResponseCodeBlock>
As you can see by the response, the [captureId](https://graphql.braintreepayments.com/reference/#object--paypaltransactiondetails) field is null because the account has yet to be charged.
#### Capturing greater than authorization amount
You can't settle more than the authorized amount unless your industry and processor support settlement adjustment (settling a certain percentage over the authorized amount); [contact us](https://developer.paypal.com/braintree/help/) for details. If your capture amount exceeds the allowable limit you will receive the respective [settlement response code](https://developer.paypal.com/braintree/docs/reference/general/processor-responses/settlement-responses).
#### Capturing multiple partial amounts against the same authorization
If you send physical goods to customers in multiple shipments, you can capture the total authorized amount across multiple partial settlements using [partialCaptureTransaction](https://graphql.braintreepayments.com/reference/#Mutation--partialCaptureTransaction).
### Recurring transactions
Use the [paymentInitiator](https://graphql.braintreepayments.com/reference/#enum--paymentinitiator) parameter with a value of recurring if the customer is not present when you create a PayPal transaction from their Vault record. Typical examples are a recurring subscription or an automatic top-up charge.
> NOTE
You won't need to do this if you're using our [recurring billing system](https://developer.paypal.com/braintree/docs/guides/recurring-billing/overview) – our logic creates subscription transactions with this parameter automatically. If you've built your own recurring logic, though, be sure your transaction sale calls include the recurring parameter.
<MutationCodeBlock>
{`mutation ChargePayPalAccount($input: ChargePayPalAccountInput!){
chargePayPalAccount(input: $input) {
transaction {
id
amount {
value
currencyCode
}
paymentMethodSnapshot {
...on PayPalTransactionDetails{
captureId
payerStatus
sellerProtectionStatus
}
}
}
}
}`}
</MutationCodeBlock>
<VariablesCodeBlock>
{`{
"input": {
"paymentMethodId": "fake-paypal-one-time-nonce",
"transaction": {
"amount": "10.00",
"paymentInitiator": "RECURRING"
}
}
}`}
</VariablesCodeBlock>
<ResponseCodeBlock>
{`{
"data": {
"chargePayPalAccount": {
"transaction": {
"id": "dHJhbnNhY3Rpb25fcm5kZDB2YTM",
"amount": {
"value": "10.00",
"currencyCode": "USD"
},
"paymentMethodSnapshot": {
"captureId": "CAPTURE-8a510f1189f0",
"payerStatus": "VERIFIED",
"sellerProtectionStatus": "ELIGIBLE"
}
}
}
},
"extensions": {
"requestId": "3a765f9e-4fde-4570-889a-2cdb16c3a231"
}
}`}
</ResponseCodeBlock>