I am making a website in which users of a website can pay each other on-site like a fiver, Upwork and other platforms.
I want to use the PayPal payment gateway for this purpose. And using Django-rest-framework at the backend.
Are there any tutorials or documentation you guys can refer me to?
here is code when I try to send request to Paypal using payee method.
class PaymentP2P(APIView):
permission_classes = ()
# authentication_classes = (SessionAuthentication, TokenAuthentication)
def post(self,request):
email_request=request.data['payee']
price_to_pay = str(request.data['price'])
payment = paypalrestsdk.Payment(self.build_request_body(email_request,price_to_pay))
print(payment)
if payment.create():
print("Payment created successfully")
else:
print(payment.error)
return Response({'paymentID':payment.id},status=200)
#staticmethod
def build_request_body(email_user="payee#email.com",price="220.00"):
"""Method to create body with a custom PAYEE (receiver)"""
return \
{
"intent": "AUTHORIZE",
"purchase_units": [
{
"amount": {
"total": price,
"currency": "USD"
},
"payee": {
"email_address": "sb-loe4o1374588#personal.example.com"
},
},
]
}
For one user to pay another user's email, you can use PayPal Checkout with a payee variable: https://developer.paypal.com/docs/checkout/integration-features/custom-payee/
Here are some front-end demo patterns of the basic checkout:
One that calls endpoints on your server to set up and capture
transactions:
https://developer.paypal.com/demo/checkout/#/pattern/server
One that
does not do that, and only uses client-side js:
https://developer.paypal.com/demo/checkout/#/pattern/client
I created PayPal Sandbox Business Account with EUR, USD and PLN enabled.
I created Sandbox REST API linked to account above.
I linked my Paypal Account in Braintree Sandbox ( https://sandbox.braintreegateway.com/ ) in Account -> My User.
I typed in REST API keys in Settings -> Processing -> PayPal.
I made sure my default merechant is PLN currency.
I created backend methods for ClientToken and ProcessingNounce using Braintree .NET docs.
I prepared frontend using dropin from Braintree docs.
Code:
braintree.dropin.create({
authorization: result.token,
container: '#dropin-braintree-container',
paypal: {
flow: 'checkout',
amount: '#Model.TransactionDetails.CalculatedTotalPrice',
currency: 'PLN'
}, function (createErr, instance) { ... /* button listener and processing stuff here */ ... });
The code above works fine! I can finish transaction with Paypal client EUR account, Paypal client PLN, Braintree credit card etc.
Client told me that he don't want to recive payment in PLN currency, but in EUR, and there I am having a trouble.
I changed line:
currency: 'EUR'
And also I changed default merechant in Braintree to EUR (without changing merechant I was getting "The currency of this PayPal transaction must match the currency of the merchant account (2091)")
Now when I try to pay with any PayPal account and any option within I am getting "The customer's bank is unwilling to accept the transaction. For credit/debit card transactions, the customer will need to contact their bank for more details regarding this generic decline; if this is a PayPal transaction, the customer will need to contact PayPal. (Declined: 2046)". I can finish transaction only using braintree sample cards.
There is no way to debug this, API Calls in PayPal are telling me something is wrong, but I can't click and view details:
When I switch back to PLN in frontend code and to default PLN merechant in Braintree, transaction works fine again.
I need help with that, it's not possible to debug it. Idk if I am missing some params specific for EUR currency or if its PayPal bug.
Thanks for help in advance!
EDIT: I have digged deeper, I checked POST request in Chrome dev tools on Sandbox Api Calls page to get details:
{
"create_time":"30 Jan 2019 05:07:53",
"correlation_id":"304384c194ece",
"resource_id":"PAY-6JB373950C8856440LRI2DGI",
"api_response":{
"additional_properties":"xxxxxx",
"body":{
"debug_id":"304384c194ece",
"details":"xxxxxx",
"information_link":"https://developer.paypal.com/docs/api/payments/#errors",
"message":"The request was refused",
"name":"TRANSACTION_REFUSED"
},
"duration_time":"xxxxxx",
"header":{
"APPLICATION_ID":"xxxxxx",
"CALLER_ACCT_NUM":"LG4QN5BPXPW7N",
"Content-Language":"*",
"Date":"Wed, 30 Jan 2019 13:07:57 GMT",
"paypal-debug-id":"304384c194ece"
},
"status":400
},
"client_id":"ASKLWoEWn6q9ZNqkzpj7pulX4x0h9iD-Fy6_yzyfKaiNlHz7VMVwgPlk6Hpaq5-pG3_pcA84qIzOEx9q",
"api_request":{
"additional_properties":"xxxxxx",
"body":{
"payer_id":"CCD9AZVEJK8UN",
"transactions":[
{
"amount":{
"currency":"EUR",
"total":"22.00"
},
"payment_options":{
"allowed_payment_method":"IMMEDIATE_PAY"
}
}
]
},
"header":{
"accept":"application/json",
"accept-encoding":"gzip, deflate",
"authorization":"xxxxxx",
"client-auth":"No cert",
"content-length":"152",
"content-type":"application/json",
"host":"api.sandbox.paypal.com",
"paypal-client-metadata-id":"EC-6DS628633U9315453",
"paypal-request-id":"1548853672_qc053cdc",
"pp_remote_addr":"xxxxxx",
"user-agent":"Braintree/1.0",
"x-ads-si-context":"xxxxxx",
"x-newrelic-id":"UAMPU1RWGwEJVlNaAQk=",
"x-newrelic-transaction":"PxQFUVYHXAtTAlhWBwUCUAUHFB8EBw8RVU4aBAoOUgYBXAAFCARRVVMAA0NKQQ8FCFADA1UIFTs=",
"x-pp-ads-performed":"xxxxxx",
"x-pp-ads-request-id":"xxxxxx",
"x-pp-ads-usecase-id":"xxxxxx",
"x-pp-anomaly-detection-mechanism":"xxxxxx",
"x-pp-corrid":"304384c194ece",
"x-pp-idempotencyid":"304384c194ece_1548853673",
"x-pp-silover":"xxxxxx",
"x-pp-slingshot-targetapp":"apiplatformproxyserv",
"x-request-id":"xxxxxx",
"x-slr-orig-script_uri":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-6JB373950C8856440LRI2DGI/execute"
},
"method":"POST"
},
"account_number":"2117554163912301260",
"http_status":400,
"url":"/v1/payments/payment/PAY-6JB373950C8856440LRI2DGI/execute"
}
According to docs this error can be basically anything.
EDIT2:
Sample request of successfull payment in PLN:
{
"create_time":"30 Jan 2019 06:58:59",
"correlation_id":"7cabc2b46e5bb",
"resource_id":"PAY-305699707J366792MLRI3XEA",
"api_response":{
"additional_properties":"xxxxxx",
"body":{
"cart":"29R95576JY4406634",
"create_time":"2019-01-30T14:59:03Z",
"id":"PAY-305699707J366792MLRI3XEA",
"intent":"sale",
"links":[
{
"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-305699707J366792MLRI3XEA",
"method":"GET",
"rel":"self"
}
],
"payer":{
"payer_info":{
"country_code":"DE",
"email":"*****",
"first_name":"*****",
"last_name":"*****",
"payer_id":"CCD9AZVEJK8UN"
},
"payment_method":"paypal",
"status":"VERIFIED"
},
"state":"approved",
"transactions":[
{
"amount":{
"currency":"PLN",
"details":"xxxxxx",
"total":"22.00"
},
"payee":{
"email":"*****",
"merchant_id":"LG4QN5BPXPW7N"
},
"payment_options":{
"allowed_payment_method":"IMMEDIATE_PAY",
"recurring_flag":"xxxxxx",
"skip_fmf":"xxxxxx"
},
"related_resources":[
{
"sale":{
"amount":{
"currency":"PLN",
"details":{
"subtotal":"22.00"
},
"total":"22.00"
},
"create_time":"2019-01-30T14:59:02Z",
"id":"4AK709636U844620F",
"links":[
{
"href":"https://api.sandbox.paypal.com/v1/payments/sale/4AK709636U844620F",
"method":"GET",
"rel":"self"
},
{
"href":"https://api.sandbox.paypal.com/v1/payments/sale/4AK709636U844620F/refund",
"method":"POST",
"rel":"refund"
},
{
"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-305699707J366792MLRI3XEA",
"method":"GET",
"rel":"parent_payment"
}
],
"parent_payment":"PAY-305699707J366792MLRI3XEA",
"payment_mode":"INSTANT_TRANSFER",
"protection_eligibility":"ELIGIBLE",
"protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE",
"state":"completed",
"transaction_fee":{
"currency":"PLN",
"value":"2.21"
},
"update_time":"2019-01-30T14:59:02Z"
}
}
]
}
]
},
"duration_time":"xxxxxx",
"header":{
"APPLICATION_ID":"xxxxxx",
"CALLER_ACCT_NUM":"LG4QN5BPXPW7N",
"Content-Language":"*",
"Date":"Wed, 30 Jan 2019 14:59:03 GMT",
"paypal-debug-id":"7cabc2b46e5bb"
},
"status":200
},
"client_id":"ASKLWoEWn6q9ZNqkzpj7pulX4x0h9iD-Fy6_yzyfKaiNlHz7VMVwgPlk6Hpaq5-pG3_pcA84qIzOEx9q",
"api_request":{
"additional_properties":"xxxxxx",
"body":{
"payer_id":"CCD9AZVEJK8UN",
"transactions":[
{
"amount":{
"currency":"PLN",
"total":"22.00"
},
"payment_options":{
"allowed_payment_method":"IMMEDIATE_PAY"
}
}
]
},
"header":{
"accept":"application/json",
"accept-encoding":"gzip, deflate",
"authorization":"xxxxxx",
"client-auth":"No cert",
"content-length":"152",
"content-type":"application/json",
"host":"api.sandbox.paypal.com",
"paypal-client-metadata-id":"EC-29R95576JY4406634",
"paypal-request-id":"1548860338_ae402q2s",
"pp_remote_addr":"xxxxxx",
"user-agent":"Braintree/1.0",
"x-ads-si-context":"xxxxxx",
"x-newrelic-id":"UAMPU1RWGwEJVlNaAQk=",
"x-newrelic-transaction":"PxRUBAIHCwsDXFJXVQdVB1YAFB8EBw8RVU4aVFxbUFQCVg9WCQdSA11UBUNKQQ8FCFADA1UIFTs=",
"x-pp-ads-performed":"xxxxxx",
"x-pp-ads-request-id":"xxxxxx",
"x-pp-ads-usecase-id":"xxxxxx",
"x-pp-anomaly-detection-mechanism":"xxxxxx",
"x-pp-corrid":"7cabc2b46e5bb",
"x-pp-idempotencyid":"7cabc2b46e5bb_1548860339",
"x-pp-silover":"xxxxxx",
"x-pp-slingshot-targetapp":"apiplatformproxyserv",
"x-request-id":"xxxxxx",
"x-slr-orig-script_uri":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-305699707J366792MLRI3XEA/execute"
},
"method":"POST"
},
"account_number":"2117554163912301260",
"http_status":200,
"url":"/v1/payments/payment/PAY-305699707J366792MLRI3XEA/execute"
}
I repeated:
1. I created PayPal Sandbox Business Account with EUR, USD and PLN enabled.
2. I created Sandbox REST API linked to account above.
4. I typed in REST API keys in Settings -> Processing -> PayPal. (in Braintree sandbox)
And it works now. I double checked, setting are exactly the same as previous. I remeber in the 1 step I added EUR currency later, so it might be some kind of PayPal bug. Or maybe REST API App doesn't update currency settings from account.
So, I am trying to figure this out but cannot seem to get this right.
I am trying to integrate paypal express onto a website. I have the sandbox environment with the facilitator and buyer accounts.
I paste in the sample code and change the client values and transaction details etc... like so:
paypal.Button.render({
env: 'sandbox', // Optional: specify 'sandbox' environment
client: {
sandbox: 'My Client ID here'
},
payment: function () {
var env = this.props.env;
var client = this.props.client;
return paypal.rest.payment.create(env, client, {
intent: "sale",
payer: { payment_method: "paypal" },
transactions: [
{
amount: { total: '14.00', currency: 'GBP' },
description: "This is a payment description"
},
],
redirect_urls: {
return_url: "http://somesite.com/success",
cancel_url: "http://somesite.com/cancel"
}
});
},
commit: true, // Optional: show a 'Pay Now' button in the checkout flow
onAuthorize: function (data, actions) {
// Optional: display a confirmation page here
alert('confirmation here');
return actions.payment.execute().then(function () {
// Show a success page to the buyer
alert('success here');
});
}
}, '#paypal-button');
The issue I am facing is that when you hit the paypal button - in the popup I do not see the amount.
Then when continuing, I get an error from javascript like so:
JavaScript runtime error: Error: Payment Api response error:
{
"name": "INTERNAL_SERVICE_ERROR",
"message": "An internal service error has occurred",
"information_link": "https://developer.paypal.com/docs/api/#INTERNAL_SERVICE_ERROR",
"debug_id": "a9ceebeb96bab"
}
Error: Payment Api response error:
{
"name": "INTERNAL_SERVICE_ERROR",
"message": "An internal service error has occurred",
"information_link": "https://developer.paypal.com/docs/api/#INTERNAL_SERVICE_ERROR",
"debug_id": "a9ceebeb96bab"
}
at Anonymous function (https://www.paypalobjects.com/api/checkout.js:8325:17)
at _loop2 (https://www.paypalobjects.com/api/checkout.js:1509:25)
at SyncPromise.prototype.dispatch (https://www.paypalobjects.com/api/checkout.js:1542:17)
at SyncPromise.prototype.resolve (https://www.paypalobjects.com/api/checkout.js:1480:13)
at Anonymous function (https://www.paypalobjects.com/api/checkout.js:1533:25)
at _loop2 (https://www.paypalobjects.com/api/checkout.js:1509:25)
at SyncPromise.prototype.dispatch (https://www.paypalobjects.com/api/checkout.js:1542:17)
at SyncPromise.prototype.resolve (https://www.paypalobjects.com/api/checkout.js:1480:13)
at Anonymous function (https://www.paypalobjects.com/api/checkout.js:1533:25)
at _loop2 (https://www.paypalobjects.com/api/checkout.js:1509:25)
So how the heck do I know what the error is?
Second question: Hopefully when this is all working with your help, how can I get back the response and determine if its a success or failure of payment along with detailed information to log it on my website and display to the user? What about custom variables like paymentID generated from my site? Can I get that information back?
Thank you
You're missing some important information for the API.
Things like AMOUNT{}, and others.
https://developer.paypal.com/docs/integration/direct/create-process-order/
I have a problem with this as well, I can get to the actions.payment.execute() and I get an error, _loop2 etc etc.