Upgrade Your PayPal Commerce Platform Integration
DocsLast updated: June 15th 2023, @ 5:00:00 pm
Upgrade your existing integration of the PayPal Commerce Platform to use version 2 of the Orders and Payments API. The upgrade enables you to leverage the existing features you've been using and gives you the following additional functionality:
- Synchronous payment mechanics--real-time payments completion
- Mixed mode payment disbursements--gives you the ability to choose between instant and delayed payouts on a per-transaction basis
Summary of changes
While there's no change in the overall integration pattern for creating orders or buyer approval, checkout is complete as soon as the Complete Order API is called with a
capture-id
sent in the response. Version 2 of orders does not support asynchronous calls.Orders API endpoints are now at
/v2/checkout/orders
and are noted in the appropriate calls in the v2 integration guide. Notable difference is with the pay for an order call. Pay for an Order is now Capture Payment for an Order:/v2/checkout/orders/{id}/capture
.Payments API endpoints are now at
/v2/payments
. Notable difference is with the refund endpoint. Refund an Order is now at/v2/payments/captures/{id}/refund
.Several existing sub-resources have some redefinition and other sub-resources are new additions:
Sub-resource State and location address
Moved under the shipping
sub-resourcecity
Replaced with admin_area_2
underaddress
state
Replaced with admin_area_1
underaddress
disbursement_mode
Moved from the root to inside the purchase_unit
of the v2 Create Order call within thepayment_instruction
amount
Redefined with a breakdown
payment_details
Renamed to payment_instruction
and moved from the root intopurchase_units
gross_total_amount
Renamed as amount
partner_fee
Generalized under platform_fees
withinpayment_instruction
payer-info
Renamed as payer
Note: Orders v2 currently supports only one (1)
purchase_units
.A reduced response payload containing only new information. If you need the full response payload, pass
"Prefer": "return=representation"
in the headers of your request.During the create order call, the
intent
value should be set toCAPTURE
.You can now update an order using a
PATCH
endpoint.
Get permissions
To use the latest versions of the API, you'll need to have your account manager update the scopes added to your API credentials. Use of the v2 API will result in the HTTP status code of 401 Unauthorized
, even in sandbox, until your account is updated.
- Log into the PayPal Developer Dashboard.
- Click on My Apps & Credentials and scroll down to the REST API apps section.
- Click on your application for the PayPal Commerce Platform.
- Send the sandbox client ID shown on the resulting page and the email used on your PayPal business account to your PayPal account manager to add the new scopes.
Create order
To update your create orders calls:
- Update the URL to
/v2/checkout/orders
. - Add the
intent
property with a value ofCAPTURE
. - Send any partner fees in
payment_instruction
underplatform_fees
. - Configure delayed disbursement features under the
payment_instruction
.
Comparison of requests
- Orders v1
- Orders v2
1curl -v -k POST https://api-m.sandbox.paypal.com/v1/checkout/orders -H 'PayPal-Partner-Attribution-Id: BN-CODE' -H 'Content-Type: application/json' -H "Authorization: Bearer ACCESS-TOKEN" -d '{2 "purchase_units": [{3 "reference_id": "store_mobile_world_order_1234",4 "description": "Mobile World Store order-1234",5 "amount": {6 "currency": "USD",7 "details": {8 "subtotal": "1.09",9 "shipping": "0.02",10 "tax": "0.33"11 },12 "total": "1.44"13 },14 "payee": {15 "email": "seller@example.com"16 },17 "items": [{18 "name": "NeoPhone",19 "sku": "sku03",20 "price": "0.54",21 "currency": "USD",22 "quantity": "1"23 },24 {25 "name": "Fitness Watch",26 "sku": "sku04",27 "price": "0.55",28 "currency": "USD",29 "quantity": "1"30 }31 ],32 "shipping_address": {33 "line1": "123 Main St",34 "line2": "",35 "city": "Anytown",36 "country_code": "US",37 "postal_code": "12345",38 "state": "CA",39 "phone": "(123) 456-7890"40 },41 "shipping_method": "United Postal Service",42 "partner_fee_details": {43 "receiver": {44 "email": "partner@example.com"45 },46 "amount": {47 "value": "0.01",48 "currency": "USD"49 }50 },51 "payment_linked_group": 1,52 "custom": "custom_value_2388",53 "invoice_number": "invoice_number_2388",54 "payment_descriptor": "Payment Mobile World"55 }],56 "redirect_urls": {57 "return_url": "https://example.com/return",58 "cancel_url": "https://example.com/cancel"59 }60}'
Comparison of responses
- Orders v1
- Orders v2 minimal
- Orders v2 full
1{2 "id": "8RU61172JS455403V",3 "gross_total_amount": {4 "value": "1.44",5 "currency": "USD"6 },7 "purchase_units": [8 {9 "reference_id": "store_mobile_world_order_1234",10 "description": "Mobile World Store order-1234",11 "amount": {12 "currency": "USD",13 "details": {14 "subtotal": "1.09",15 "shipping": "0.02",16 "tax": "0.33"17 },18 "total": "1.44"19 },20 "payee": {21 "email": "seller@example.com"22 },23 "items": [24 {25 "name": "NeoPhone",26 "sku": "sku03",27 "price": "0.54",28 "currency": "USD",29 "quantity": "1"30 },31 {32 "name": "Fitness Watch",33 "sku": "sku04",34 "price": "0.55",35 "currency": "USD",36 "quantity": "1"37 }38 ],39 "shipping_address": {40 "recipient_name": "Fullname Lastname",41 "default_address": false,42 "preferred_address": false,43 "primary_address": false,44 "disable_for_transaction": false,45 "line1": "123 Main St",46 "line2": "",47 "city": "Anytown",48 "country_code": "US",49 "postal_code": "12345",50 "state": "CA",51 "phone": "(123) 456-7890"52 },53 "shipping_method": "United Postal Service",54 "partner_fee_details": {55 "receiver": {56 "email": "partner@example.com"57 },58 "amount": {59 "value": "0.01",60 "currency": "USD"61 }62 },63 "payment_linked_group": 1,64 "custom": "custom_value_2388",65 "invoice_number": "invoice_number_2388",66 "payment_descriptor": "Payment Mobile World",67 "status": "CAPTURED"68 }69 ],70 "redirect_urls": {71 "return_url": "https://example.com/return",72 "cancel_url": "https://example.com/cancel"73 },74 "create_time": "2017-04-26T21:18:49Z",75 "links": [76 {77 "href": "https://api-m.paypal.com/v1/checkout/orders/8RU61172JS455403V",78 "rel": "self",79 "method": "GET"80 },81 {82 "href": "https://api-m.sandbox.paypal.com/webapps/hermes?token=8RU61172JS455403V",83 "rel": "approval_url",84 "method": "GET"85 },86 {87 "href": "https://api-m.paypal.com/v1/checkout/orders/8RU61172JS455403V",88 "rel": "cancel",89 "method": "DELETE"90 }91 ],92 "status": "CREATED"93}
Capture an order
Pay an order is now capture an order. To upgrade your pay an order calls to capture an order:
- Update the URL to
/v2/checkout/orders/ORDER-ID/capture
. disbursement_mode
andpayer
are now now sent in the Create Order call.- You can pass a new
payment_source
object in the request body when initiating a transaction from a vaulted payment method such as a billing agreement.
Comparison of requests
- Orders v1
- Orders v2
1curl -v https://api-m.sandbox.paypal.com/v1/checkout/orders/5O190127TN364715T/pay2 -X POST -H "PayPal-Client-Metadata-Id: 1495725899514oren"3 -H "PayPal-Request-Id: 9c5e3668-cb92-4a40-99b7-c74cb68913f4"4 -H "PayPal-Partner-Attribution-Id: BN-CODE"5 -H "Authorization: Bearer ACCESS-TOKEN"6 -H "Content-Type: application/json"7 -d ‘{8 "disbursement_mode": "INSTANT"9}
Comparison of responses
- Orders v1
- Orders v2 minimal
- Orders v2 full
1{2 "order_id": "5O190127TN364715T",3 "status": "APPROVED",4 "payer_info": {5 "email": "payer@example.com",6 "first_name": "Firstname",7 "last_name": "Lastname",8 "payer_id": "9WVBNYPKKNBJS",9 "phone": "1234567890",10 "country_code": "US",11 "shipping_address": {12 "recipient_name": "Firstname Lastname",13 "default_address": false,14 "preferred_address": false,15 "primary_address": false,16 "disable_for_transaction": false,17 "line1": "123 Main St",18 "line2": "",19 "city": "Anytown",20 "country_code": "US",21 "postal_code": "12345",22 "state": "CA"23 }24 },25 "create_time": "2017-04-26T21:21:50Z",26 "update_time": "2017-04-26T21:21:50Z",27 "links": [28 {29 "href": "https://api-m.paypal.com/v1/checkout/orders/8RU61172JS455403V",30 "rel": "self",31 "method": "GET"32 }]33}
Show an order
The request to show an order is the same. The URL of the endpoint is now /v2/checkout/orders/{order_id}
. The response has changed slightly.
Comparison of responses
- Orders v1
- Orders v2
1{2"id": "8SC68793353299025",3"status": "CREATED",4"gross_total_amount": {5 "value": "1.44",6 "currency": "USD"7},8"application_context": {},9"purchase_units": [{10 "reference_id": "store_mobile_world_order_1234",11 "description": "Mobile World Store order-1234",12 "amount": {13 "currency": "USD",14 "details": {15 "subtotal": "1.09",16 "shipping": "0.02",17 "tax": "0.33"18 },19 "total": "1.44"20 },21 "payee": {22 "email": "seller@example.com"23 },24 "items": [{25 "name": "NeoPhone",26 "sku": "sku03",27 "price": "0.54",28 "currency": "USD",29 "quantity": 130 },31 {32 "name": "Fitness Watch",33 "sku": "sku04",34 "price": "0.55",35 "currency": "USD",36 "quantity": 137 }38 ],39 "shipping_address": {40 "line1": "123 Main St",41 "line2": "",42 "city": "Anytown",43 "country_code": "US",44 "postal_code": "12345",45 "state": "CA",46 "phone": "(123) 456-7890"47 },48 "shipping_method": "United Postal Service",49 "partner_fee_details": {50 "receiver": {51 "email": "partner@example.com"52 },53 "amount": {54 "value": "0.01",55 "currency": "USD"56 }57 },58 "payment_linked_group": 1,59 "custom": "custom_value_2388",60 "invoice_number": "invoice_number_2388",61 "payment_descriptor": "Payment Mobile World",62 "status": "NOT_PROCESSED"63}],64"redirect_urls": {65 "return_url": "https://example.com/return",66 "cancel_url": "https://example.com/cancel"67},68"links": [{69 "href": "https://api-m.sandbox.paypal.com/v1/checkout/orders/8SC68793353299025",70 "rel": "self",71 "method": "GET"72 },73 {74 "href": "https://api-m.sandbox.paypal.com/checkoutnow?token=8SC68793353299025",75 "rel": "approval_url",76 "method": "REDIRECT"77 }78],79"create_time": "2018-09-21T17:22:45Z"80}
Refunds
The /v2/payments/captures/{id}/refund
endpoint is now the endpoint for all post-payment operations. You can use this endpoint with any existing orders created using the v1 endpoint.
Comparison of requests
These samples show a full refund.
- Orders v1
- Orders v2
1curl -v -X POST https://api-m.sandbox.paypal.com/v1/payments/capture/3CB62566PT644045J/refund2 -H "Authorization: Bearer ACCESS-TOKEN"3 -H "Content-Type: application/json"
Comparison of responses
- Orders v1
- Orders v2 minimal
- Orders v2 full
1{2 "id": "1JU08902781691411",3 "status": "COMPLETED",4 "links": [5 {6 "rel": "self",7 "method": "GET",8 "href": "https://api-m.paypal.com/v1/payments/refunds/1JU08902781691411"9 },10 {11 "rel": "up",12 "method": "GET",13 "href": "https://api-m.paypal.com/v1/payments/captures/2GG279541U471931P"14 }15 ]16}
Webhooks
The new synchronous nature of the call change in v2 means there are slight differences in the payment webhooks sent.
v1 Webhooks | v2 Webhooks |
---|---|
Response: 200 OK | Response: 201 Created |
CHECKOUT.ORDER.PROCESSED is sent when the order gets picked up from the queue and processed along with the order status. | CHECKOUT.ORDER.COMPLETED is sent when the order status gets moved to COMPLETED upon a successful order/capture call. |
PAYMENT.CAPTURE.DENIED is sent when the payment is denied. | None. An appropriate HTTP error response code is sent on the order/capture call. |
PAYMENT.CAPTURE.COMPLETED is sent whenever the payment is successfully processed. | Same. |
PAYMENT.CAPTURE.REFUNDED is sent whenever a payment has been refunded. | Same. |
Reference
For more information on the v2 API and their endpoints, see: