I am using Postman for this. It generates the following link https://www.sandbox.paypal.com/webapps/billing/subscriptions?ba_token=BA-79D58732NX9686808 however when I visit it, I see the following error message:
Things don't appear to be working at the moment. Please try again later.
After getting a token, I created a product then I created a plan and finally, I created a subscription. Am I missing something?
Here is what I have done and the response I have received:
Create Product:
{
"id": "FF-SUBSCRIPTION-SERVICE-BASIC-T1",
"name": "Subscription Basic Plan",
"description": "Basic Service Subscription Plan",
"type": "SERVICE"
}
Create Plan:
{
"product_id": "FF-SUBSCRIPTION-SERVICE-BASIC-T1",
"name": "Subscription Basic Plan",
"description": "Basic Service Subscription Plan",
"status": "ACTIVE",
"payment_preferences": {
"auto_bill_outstanding": true,
"payment_failure_threshold": 5
},
"billing_cycles": [
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "TRIAL",
"sequence": 1,
"total_cycles": 1
},
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 2,
"total_cycles": 0,
"pricing_scheme": {
"fixed_price": {
"value": "14.99",
"currency_code": "USD"
}
}
}
]
}
Create Subscription:
{
"plan_id": "P-1DM03386YX156733CMNORKJQ",
"quantity": "1",
"shipping_amount": {
"currency_code": "USD",
"value": "14.99"
},
"subscriber": {
"name": {
"given_name": "John",
"surname": "Doe"
},
"email_address": "sb-xahhi21980157#personal.example.com"
}
},
"application_context": {
"brand_name": "X",
"locale": "en-US",
"shipping_preference": "SET_PROVIDED_ADDRESS",
"user_action": "SUBSCRIBE_NOW",
"payment_method": {
"payer_selected": "PAYPAL",
"payee_preferred": "IMMEDIATE_PAYMENT_REQUIRED"
},
"return_url": "https://www.example.com/returnUrl",
"cancel_url": "https://www.example.com/cancelUrl"
}
}
The response I receive is as follows:
{
"status": "APPROVAL_PENDING",
"id": "I-N6DFDLTU8HK9",
"create_time": "2022-10-29T11:58:28Z",
"links": [
{
"href": "https://www.sandbox.paypal.com/webapps/billing/subscriptions?ba_token=BA-79D58732NX9686808",
"rel": "approve",
"method": "GET"
},
{
"href": "https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-N6DFDLTU8HK9",
"rel": "edit",
"method": "PATCH"
},
{
"href": "https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-N6DFDLTU8HK9",
"rel": "self",
"method": "GET"
}
]
}
Related
I have got a PayPal Advanced Checkout Sandbox set up and capturing the order using the API call below:
/v2/checkout/orders/{{order_id}}/capture
Below are the transaction details I send to create the order:
{
"intent": "CAPTURE",
"payer": {
"address": {
"admin_area_2": "Downton",
"postal_code": "SP5",
"country_code": "GB"
}
},
"purchase_units": [
{
"description": "Test Item",
"custom_id": "12345",
"soft_descriptor": "Purchase Descriptior",
"amount": {
"currency_code": "USD",
"value": "58.80",
"breakdown": {
"item_total": {
"currency_code": "USD",
"value": "49.00"
},
"tax_total": {
"currency_code": "USD",
"value": "9.80"
}
}
},
"items": [
{
"name": "Test Item",
"unit_amount": {
"currency_code": "USD",
"value": "49.00"
},
"tax": {
"currency_code": "USD",
"value": "9.80"
},
"quantity": 1,
"category": "PHYSICAL_GOODS"
}
],
"shipping": {}
}
]
}
And then once it has been paid with a sandbox personal account the order capture response is below:
{
"id": "4FS9138999682320N",
"status": "COMPLETED",
"payment_source": {
"paypal": {
"email_address": "sb-bdd43g21513704#personal.example.com",
"account_id": "V7ZN4NEJRLGZA",
"name": {
"given_name": "John",
"surname": "Doe"
},
"address": {
"country_code": "GB"
}
}
},
"purchase_units": [
{
"reference_id": "default",
"shipping": {
"name": {
"full_name": "John Doe"
},
"address": {
"address_line_1": "Whittaker House",
"address_line_2": "2 Whittaker Avenue",
"admin_area_2": "Richmond",
"admin_area_1": "Surrey",
"postal_code": "TW9 1EH",
"country_code": "GB"
}
},
"payments": {
"captures": [
{
"id": "40V95236PS9814847",
"status": "COMPLETED",
"amount": {
"currency_code": "USD",
"value": "58.80"
},
"final_capture": true,
"seller_protection": {
"status": "ELIGIBLE",
"dispute_categories": [
"ITEM_NOT_RECEIVED",
"UNAUTHORIZED_TRANSACTION"
]
},
"seller_receivable_breakdown": {
"gross_amount": {
"currency_code": "USD",
"value": "58.80"
},
"paypal_fee": {
"currency_code": "USD",
"value": "2.30"
},
"net_amount": {
"currency_code": "USD",
"value": "56.50"
}
},
"custom_id": "12345",
"links": [
{
"href": "https://api.sandbox.paypal.com/v2/payments/captures/40V95236PS9814847",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v2/payments/captures/40V95236PS9814847/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/4FS9138999682320N",
"rel": "up",
"method": "GET"
}
],
"create_time": "2022-10-31T16:42:07Z",
"update_time": "2022-10-31T16:42:07Z"
}
]
}
}
],
"payer": {
"name": {
"given_name": "John",
"surname": "Doe"
},
"email_address": "sb-bdd43g21513704#personal.example.com",
"payer_id": "V7ZN4NEJRLGZA",
"address": {
"country_code": "GB"
}
},
"links": [
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/4FS9138999682320N",
"rel": "self",
"method": "GET"
}
]
}
I get a status: COMPLETED as the response but it is not returning the exchange_rate value even though the payer currency is different to the payee currency.
Does anyone know why this is?
The example is a USD transaction, the payee account received USD.
If the payer used a funding source of a different currency to fund the transaction, this will not be visible to the receiver or API facilitator. Any such sender currency conversion is between the payer and PayPal; all you know (and all you need to know) is you received the requested USD amount via PayPal.
I am trying to trigger CUSTOMER.DISPUTE.RESOLVED event for disputes testing in sandbox, for that i made a test payment and opened a dispute in the resolution center. To trigger dispute resolved event i wanna call settle dispute method https://developer.paypal.com/docs/api/customer-disputes/v1#disputes-actions_adjudicate.
However i am not able to do that, cuz after create dispute is in WAITING_FOR_SELLER_RESPONSE status and i allowed only to call accept claim and provide evidence.
After accept claim i am able only to call provide supporting info method, settle method is still not allowed.
So my question is how to trigger CUSTOMER.DISPUTE.RESOLVED event in sandbox and on what dispute state i need to call settle method from here https://developer.paypal.com/docs/api/customer-disputes/v1#disputes-actions_adjudicate?
Request/Response examples
Dispute details right after open
{
"dispute_id": "PP-D-40523",
"create_time": "2021-03-03T08:47:08.000Z",
"update_time": "2021-03-03T08:48:12.000Z",
"disputed_transactions": [
{
"buyer_transaction_id": "35703532VD052404F",
"seller_transaction_id": "92198049S8582070N",
"create_time": "2021-03-03T08:41:55.000Z",
"transaction_status": "COMPLETED",
"gross_amount": {
"currency_code": "USD",
"value": "29.99"
},
"buyer": {
"name": "John Doe"
},
"seller": {
"email": "sb-47flty3787626#business.example.com",
"merchant_id": "TQNC9P6W9822C",
"name": "John Doe's Test Store"
},
"items": [],
"seller_protection_eligible": true
}
],
"reason": "UNAUTHORISED",
"status": "WAITING_FOR_SELLER_RESPONSE",
"dispute_amount": {
"currency_code": "USD",
"value": "29.99"
},
"dispute_life_cycle_stage": "CHARGEBACK",
"dispute_channel": "INTERNAL",
"extensions": {
"buyer_contacted_time": "2021-02-11T17:50:48.000Z"
},
"seller_response_due_date": "2021-03-24T08:47:50.000Z",
"allowed_response_options": {
"accept_claim": {
"accept_claim_types": [
"REFUND"
]
}
},
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-40523",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-40523/provide-evidence",
"rel": "provide_evidence",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-40523/accept-claim",
"rel": "accept_claim",
"method": "POST"
}
]
}
After provide evidence
{
"dispute_id": "PP-D-40523",
"create_time": "2021-03-03T08:47:08.000Z",
"update_time": "2021-03-03T11:01:55.000Z",
"disputed_transactions": [
{
"buyer_transaction_id": "35703532VD052404F",
"seller_transaction_id": "92198049S8582070N",
"create_time": "2021-03-03T08:41:55.000Z",
"transaction_status": "COMPLETED",
"gross_amount": {
"currency_code": "USD",
"value": "29.99"
},
"buyer": {
"name": "John Doe"
},
"seller": {
"email": "sb-47flty3787626#business.example.com",
"merchant_id": "TQNC9P6W9822C",
"name": "John Doe's Test Store"
},
"items": [],
"seller_protection_eligible": true
}
],
"reason": "UNAUTHORISED",
"status": "UNDER_REVIEW",
"dispute_amount": {
"currency_code": "USD",
"value": "29.99"
},
"dispute_life_cycle_stage": "CHARGEBACK",
"dispute_channel": "INTERNAL",
"extensions": {
"buyer_contacted_time": "2021-02-11T17:50:48.000Z"
},
"evidences": [
{
"evidence_type": "OTHER",
"documents": [
{
"name": "ava.jpeg"
}
],
"notes": "Test",
"source": "SUBMITTED_BY_SELLER",
"date": "2021-03-03T11:01:56.000Z",
"action_info": {
"action": "PROVIDE_EVIDENCE"
}
}
],
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-40523",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-40523/provide-supporting-info",
"rel": "provide_supporting_info",
"method": "POST"
}
]
}
Another dispute after claim
{
"dispute_id": "PP-D-40407",
"create_time": "2021-03-02T08:17:07.000Z",
"update_time": "2021-03-02T08:47:05.000Z",
"disputed_transactions": [
{
"buyer_transaction_id": "1VS7234539684123P",
"seller_transaction_id": "2S50928513331053U",
"create_time": "2021-03-02T08:09:49.000Z",
"transaction_status": "COMPLETED",
"gross_amount": {
"currency_code": "USD",
"value": "29.99"
},
"buyer": {
"name": "John Doe"
},
"seller": {
"email": "sb-47flty3787626#business.example.com",
"merchant_id": "TQNC9P6W9822C",
"name": "John Doe's Test Store"
},
"items": [],
"seller_protection_eligible": true
}
],
"reason": "UNAUTHORISED",
"status": "UNDER_REVIEW",
"dispute_amount": {
"currency_code": "USD",
"value": "29.99"
},
"dispute_life_cycle_stage": "CHARGEBACK",
"dispute_channel": "INTERNAL",
"extensions": {
"buyer_contacted_time": "2021-02-11T17:50:48.000Z"
},
"evidences": [
{
"evidence_type": "OTHER",
"documents": [],
"notes": "Refund.",
"source": "SUBMITTED_BY_SELLER",
"date": "2021-03-02T08:47:06.000Z",
"action_info": {
"action": "ACCEPT_CLAIM",
"response_option": "REFUND"
}
}
],
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-40407",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-40407/provide-supporting-info",
"rel": "provide_supporting_info",
"method": "POST"
}
]
}
Adjudicate on dispute with evidence
Request
POST https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-40523/adjudicate
{
"adjudication_outcome": "BUYER_FAVOR"
}
Response
{
"name": "VALIDATION_ERROR",
"message": "Invalid request - see details",
"debug_id": "6aadbbc916b3c",
"information_link": "https://developer.paypal.com/docs/api/customer-disputes/v1/#errors",
"details": [
{
"issue": "ACTION_NOT_ALLOWED_IN_CURRENT_DISPUTE_STATE"
}
],
"links": []
}
You have to get it to an 'UNDER_REVIEW' by PayPal state before you can trigger the adjudication one way or the other.
So if it is 'WAITING_FOR_SELLER_RESPONSE' you should provide evidence; there is a call for that.
You may also need to make an offer and deny the offer, or escalate to claim.
This tool may be useful for understanding the potential steps: https://www.paypal.com/apex/product-profile/customerDisputes/
Using PayPal's current API I've created a simple Product:
{
"id" : "A-001",
"name": "A Service",
"description": "Video streaming service",
"type": "SERVICE",
"category": "SOFTWARE"
}
Also created a Plan, which is tiered based on Quantity
{
"product_id" : "A-001",
"name": "Default Plan",
"description": "Plan with regular and trial payment definitions.",
"quantity_supported" : true,
"billing_cycles": [
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "TRIAL",
"sequence": 1,
"total_cycles": 1
},
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 2,
"total_cycles": 12,
"pricing_scheme": {
"pricing_model" : "TIERED",
"version" : 1,
"tiers": [{
"starting_quantity": 1,
"ending_quantity": 499,
"amount": { "currency_code":"USD", "value":0.55}
},
{
"starting_quantity": 500,
"ending_quantity": 999,
"amount": { "currency_code":"USD", "value":0.5}
},
{
"starting_quantity": 1000,
"ending_quantity": 2499,
"amount": { "currency_code":"USD", "value":0.46}
},
{
"starting_quantity": 2500,
"amount": { "currency_code":"USD", "value":0.37}
}
]
}
}
],
"payment_preferences": {
"auto_bill_outstanding": true,
"setup_fee": {
"value": "10",
"currency_code": "USD"
},
"setup_fee_failure_action": "CONTINUE",
"payment_failure_threshold": 3
},
"taxes": {
"percentage": "10",
"inclusive": false
}
}
Now, I try to create a Subscription to the Plan:
{
"plan_id": "P-16786052YT8021220MAMUCDY",
"start_time": "2021-03-01T00:00:00Z",
"quantity": "20",
"shipping_amount": {
"currency_code": "USD",
"value": "0.00"
},
"subscriber": {
"name": {
"given_name": "John",
"surname": "Doe"
},
"email_address": "customer#example.com",
"shipping_address": {
"name": {
"full_name": "John Doe"
},
"address": {
"address_line_1": "2211 N First Street",
"address_line_2": "Building 17",
"admin_area_2": "San Jose",
"admin_area_1": "CA",
"postal_code": "95131",
"country_code": "US"
}
}
},
"application_context": {
"brand_name": "walmart",
"locale": "en-US",
"shipping_preference": "SET_PROVIDED_ADDRESS",
"user_action": "SUBSCRIBE_NOW",
"payment_method": {
"payer_selected": "PAYPAL",
"payee_preferred": "IMMEDIATE_PAYMENT_REQUIRED"
},
"return_url": "https://example.com/returnUrl",
"cancel_url": "https://example.com/cancelUrl"
}
}
But I get an Error response:
{
"name": "UNPROCESSABLE_ENTITY",
"message": "The requested action could not be performed, semantically incorrect, or failed business validation.",
"debug_id": "658174d246c0b",
"details": [
{
"issue": "SUBSCRIPTION_CANNOT_HAVE_QUANTITY",
"description": "Subscription can't have quantity as the plan does not support quantity."
}
],
"links": [
{
"href": "https://developer.paypal.com/docs/api/v1/billing/subscriptions#UNPROCESSABLE_ENTITY",
"rel": "information_link",
"method": "GET"
}
]
}
Why do I get this error when my Plan clearly states "quantity_supported" : true, ?
In my case I had forgotten to modify the PayPal-Request-Id from a previous Plan creation (which didn't allow Quantity), so the Plan with details above wasn't being created
Question updated - more details added.
I get a 500 (INTERNAL_SERVICE_ERROR) error from PayPal when I try to pay for an order.
I get ok from create order, and get the orderID - order status CREATED.
The order is approved by buyer - successfully and order status become APPROVED.
Order created by https://api.sandbox.paypal.com/v1/checkout/orders
Approved using paypal https://www.paypalobjects.com/api/checkout.js
{
"id": "53T50821FM697283T",
"gross_total_amount": {
"value": "26.66",
"currency": "ILS"
},
"purchase_units": [
{
"reference_id": "20180318-64466",
"amount": {
"currency": "ILS",
"total": "26.66"
},
"payee": {
"email": "d0535318380-classeeks#gmail.com"
},
"items": [
{
"name": "Meeting",
"sku": "20180318-64466",
"description": "Meeting 1/26/2018 1:00 AM-1/26/2018 2:20 AM. aaaaa",
"price": "26.66",
"currency": "ILS",
"quantity": 1
}
],
"shipping_address": {
"recipient_name": "Andrey Dyachenko",
"line1": "ישראליס 5 דירה 4",
"city": "תל-אביב",
"country_code": "IL",
"postal_code": "61014",
"state": "",
"type": "HOME_OR_WORK"
},
"partner_fee_details": {
"receiver": {
"email": "d0535318380-reciver#gmail.com"
},
"amount": {
"value": "12.66",
"currency": "ILS"
}
}
}
],
"payer_info": {
"email": "d0535318380-buyer#gmail.com",
"first_name": "Andrey",
"last_name": "Dyachenko",
"payer_id": "BZDA9RCZXKYQY",
"country_code": "IL",
"shipping_address": {
"recipient_name": "Andrey Dyachenko",
"line1": "ישראליס 5 דירה 4",
"city": "תל-אביב",
"country_code": "IL",
"postal_code": "61014",
"state": "",
"type": "HOME_OR_WORK"
}
},
"metadata": {
"supplementary_data": [
{
"name": "risk_correlation_id",
"value": "53T50821FM697283T"
},
{
"name": "buyer_ipaddress",
"value": "109.65.134.129"
},
{
"name": "external_channel",
"value": "WEB"
}
]
},
"redirect_urls": {
"return_url": "https://classeeks.com/order/details/70368c93-90db-4a8e-bd82-6d611acc2d17",
"cancel_url": "https://classeeks.com/order/details/70368c93-90db-4a8e-bd82-6d611acc2d17"
},
"create_time": "2018-03-18T19:49:11Z",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/checkout/orders/53T50821FM697283T",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/checkout/orders/53T50821FM697283T/capture",
"rel": "capture",
"method": "POST"
}
],
"status": "APPROVED"
}
Next step pay with https://api.sandbox.paypal.com/v1/checkout/orders/53T50821FM697283T/pay
{ "disbursement_mode":"DELAYED" }
Response
{
"name": "INTERNAL_SERVICE_ERROR",
"message": "The server encountered an internal error that prevented it from fulfilling this request.",
"information_link": "https://developer.paypal.com/docs/api/#INTERNAL_SERVICE_ERROR",
"debug_id": "be0c6976ab17a"
}
Based https://demo.paypal.com/us/demo/go?page=cart
If you have created the order successfully, then you can either capture the order directly or create the authorization which places the fund on hold and later you can capture the authorization. Check the doc for PayPal order APIs.
This is an edit to my original post. I think the paypal rest api sandbox is down.
The error just started and I haven't had it before:
here is the capture URL:
https://api.sandbox.paypal.com/v1/payments/payment/PAY-8EN83459YH6921921KJ4QNHQ
Its a 404 error. Here is the body:
{
name: "INVALID_RESOURCE_ID"
message: "The requested resource ID was not found"
information_link: "https://developer.paypal.com/webapps/developer/docs/api/#INVALID_RESOURCE_ID"
debug_id: "e56bae98dcc26"
}
The payment was properly created and I used the same credentials and the payment link provided in the returned payment creation response.
Here was the response from the original payment creation call:
{
"id": "PAY-8EN83459YH6921921KJ4QNHQ",
"create_time": "2013-11-05T14:54:22Z",
"update_time": "2013-11-05T14:54:30Z",
"state": "approved",
"intent": "authorize",
"payer": {
"payment_method": "credit_card",
"funding_instruments": [
{
"credit_card": {
"type": "visa",
"number": "xxxxxxxxxxxx0331",
"expire_month": "11",
"expire_year": "2018",
"first_name": "Joe",
"last_name": "Shopper",
"billing_address": {
"line1": "52 N Main ST",
"city": "Johnstown",
"state": "OH",
"postal_code": "43210",
"country_code": "US"
}
}
}
]
},
"transactions": [
{
"amount": {
"total": "7.47",
"currency": "USD",
"details": {
"subtotal": "7.41",
"tax": "0.03",
"shipping": "0.03"
}
},
"description": "This is the payment transaction description.",
"related_resources": [
{
"authorization": {
"id": "0UH21242UH1119007",
"create_time": "2013-11-05T14:54:22Z",
"update_time": "2013-11-05T14:54:30Z",
"state": "authorized",
"amount": {
"total": "7.47",
"currency": "USD",
"details": {
"subtotal": "7.41",
"tax": "0.03",
"shipping": "0.03"
}
},
"parent_payment": "PAY-8EN83459YH6921921KJ4QNHQ",
"valid_until": "2013-12-04T14:54:22Z",
"links": [
{
"href": "https:\/\/api.sandbox.paypal.com\/v1\/payments\/authorization\/0UH21242UH1119007",
"rel": "self",
"method": "GET"
},
{
"href": "https:\/\/api.sandbox.paypal.com\/v1\/payments\/authorization\/0UH21242UH1119007\/capture",
"rel": "capture",
"method": "POST"
},
{
"href": "https:\/\/api.sandbox.paypal.com\/v1\/payments\/authorization\/0UH21242UH1119007\/void",
"rel": "void",
"method": "POST"
},
{
"href": "https:\/\/api.sandbox.paypal.com\/v1\/payments\/payment\/PAY-8EN83459YH6921921KJ4QNHQ",
"rel": "parent_payment",
"method": "GET"
}
]
}
}
]
}
],
"links": [
{
"href": "https:\/\/api.sandbox.paypal.com\/v1\/payments\/payment\/PAY-8EN83459YH6921921KJ4QNHQ",
"rel": "self",
"method": "GET"
}
]
}
There is a reported problem at the moment with REST API. PayPal are working on it.
I was hitting my head against the wall for a while thinking that this PayPal bug was the cause of my problems. However, it turns out that PayPal generates the same error when you are using the wrong configuration in your client. In my case, I had the Android library set to use ENVIRONMENT_NO_NETWORK, and not ENVIRONMENT_SANDBOX. This produces real-looking transaction IDs, which (of course) are not registered with the server.