⬆️ ⬇️

We get paid through PayPal

Finished the integration of our site with the payment system PayPal . In my case, there was a small feature - we already accept payments from Robokassa and we would like to receive a similar workflow when paying. PayPal has a lot of different integration options and the biggest “difficulty” was finding the right option that matches the existing workflow.

Our workflow is very simple:



In the end, everything worked out for me, although not without small jambs (as without them).



What we need








Step 1: Set up PayPal


Go to developer.paypal.com . For this, a regular paypal account will do. Go to the Applications tab.

')

Create a new application. You should have no difficulties. Of the important parameters: "Application return URL." This is the address to which PayPal will send the user after payment (or cancellation). Also pay attention to Client ID and Secret. These are the keys by which the pipe will authorize us when using api.



Next you need to create a test account for the sandbox. Click the link Sandbox accounts create a test user (under it we will conduct test payments). Difficulties, too, should not arise.



Step 2: Test Application


Install the SDK:

Install-Package RestApiSDK 


We create a test application (for example, a console application, although I use an empty test in a project for this purpose, QuickTests). And copy-paste into it the code below, after replacing YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the parameters of our newly created application. The code, in principle, can be taken from the Interactive Guide with code examples , I just gathered it together and brought it into a pleasant form.



  var sdkConfig = new Dictionary<string, string> { { "mode", "sandbox" } }; string accessToken = new OAuthTokenCredential("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", sdkConfig) .GetAccessToken(); var redirectUrls = new RedirectUrls { cancel_url = "http://localhost:11180/PayPalResult?cancel=true", return_url = "http://localhost:11180/PayPalResult?success=true" }; var amnt = new Amount { currency = "USD", total = "1" }; var createdPayment = new Payment { intent = "sale", payer = new Payer { payment_method = "paypal" }, transactions = new List<Transaction> { new Transaction { description = "Sample payment", amount = amnt }}, redirect_urls = redirectUrls} .Create(new APIContext(accessToken) { Config = sdkConfig }); var approvalUrl = createdPayment.links.Single(l => l.rel == "approval_url").href; var paymentId = createdPayment.id; Console.WriteLine(approvalUrl); Console.WriteLine(paymentId); 




We pass on approvalUrl, log in under the test account, confirm the payment, throws us to http: // localhost: 11180 / PayPalResult? Success = true & token = EC-DSKFJDSKFJEO42M & PayerID = DFKJDFKLGJEOR (doesn’t matter if you have a web server that has a service, you have a service, you have a service provider?



Take the PayerID parameter from this URL and insert it, along with PaymentId (we received it a little earlier), into the following code:



  string payerID = "YOUR_PAYER_ID"; string paymentId = "YOUR_PAYMENT_ID"; var sdkConfig = new Dictionary<string, string> { { "mode", "sandbox" } }; string accessToken = new OAuthTokenCredential("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", sdkConfig) .GetAccessToken(); var pymntExecution = new PaymentExecution { payer_id = payerID }; var payment = new Payment { id = paymentId } .Execute(new APIContext(accessToken) { Config = sdkConfig }, pymntExecution); 




Here payment.status is important for us, which has now received the value “approved”. Hurray, the test is passed!

Documentation says that we should do Refund a sale (API reference) further, but I, for now, did not understand what it is.



Step 3: Integrating into our application


With the integration of the code above in the application, theoretically, there should be no problems. But I still had them. This problem was connected with remembering paymentId between two methods. Just remembering paymentId is not difficult, it is difficult to understand which of the remembered payments belongs to the current request. After all, paypal in resultUrl does not specify any data other than PayerID. And by PayerID get paymentIdo not work out.



You can store this value in the session and assume that the user conducts only one transaction at a time.



And you can do more cunning . You can generate an id for payment and ask PayPal to include this id in ResultUrl. Like this:

  var redirectUrls = new RedirectUrls { cancel_url = "http://localhost:11180/PayPalResult?cancel=true&InvoiceId={SOME_ID}", return_url = "http://localhost:11180/PayPalResult?success=true&InvoiceId={SOME_ID}" }; 


With this value you can already find the corresponding paymentId. In principle, it is possible to immediately transfer paymentId to RedirectUrls, but it seems to me that it is not security (although the security officer from me is so-so, these values ​​can be well protected and nothing can be obtained from them).



Conclusion


That's all. Not so difficult as it seemed. I hope someone else will find this instruction useful.



I have a couple of open integration questions. If you can answer them - I will be grateful.

Source: https://habr.com/ru/post/207446/



All Articles