How am I supposed to capture a payment 1 day after its authorization if the PayPal token expires after 3 hours? - paypal

I'm using the express checkout API through the ActiveMerchant gem in a Ruby on Rails app. The whole authorize and capture flow works just fine when is done within 3 hours. But after that my token expires and I lose the transaction. Even if the authorize and capture documentation says that the authorization is valid for 3 days (at least according to https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_admin_authcapture).
So, how can I capture the transaction after the token has expired?

You shouldn't have to be passing your token. You should be following the flow below.
Make your SetExpressCheckout API call and set payment action to authorization (A)
Get token back
Redirect buyer over to PayPal with to token to login and agree to payment
Buyer gets redirected back to your site with token and payer id returned
You can then execute your GetExpressCheckoutDetails API call using the token.(this step is optional)
Then you perform the DoExpressCheckoutPayment API where you pass over the token and set the payment action to authorization (A)
Then then completes the Express Checkout authorization.
Now you would go back a day or two later and perform your DoCapture API where you send over the transaction id that was returned from your DoExpressCheckoutPayment API earlier. You don't send over the token again here. Once you complete the DoCapture, the funds should then show in your account.

Related

PayPal Billing Agreement Token

Currently my flow is
User clicks PayPal Button
User gets redirected to PayPal approval URL
User gets redirected back to my website with a Token
I make a call to my server with the returned Token to execute the payment.
Now if user tries to refresh the page, token is passed again to my backend and subscription is processed again with same token.
Is there anyway to avoid this? Is the flow correct?

Verify Client Side Express Checkout from Server

I have implemented client side checkout as demo'd here https://developer.paypal.com/demo/checkout/#/pattern/client. Its working fine while testing with sandbox account. But I am concerned about how we can verify whether the payment has actually gone through from the server side?
For eg: if the user executed a payment for Order number 'X', I want to make sure that the payment has been successful. I noteiced the transaction Id which I understand is generated by paypal only if the payment has gone through and we can recieve that Id in the parameter for payment execute call back:
actions.payment.execute().then(function (payment) { // where payment.transactions[0].related_resources[0].sale.id is some value say 'xxx' });
The same Unique Id can be seen in the sandbox transaction details page (https://www.sandbox.paypal.com/webscr?cmd=_history-details-from-hub&id=xxx) as Unique Transaction IDxxx. Is there a way (a paypal endpoint) to verify this through a server side call? That is verfiy that the Transaction Id received at the server is a valid one from paypal.
Excuse my ignorance, are webhook events meant to do this?
You can use IPN/Webhooks, then PayPal will send a notification to you for every payment with the transaction id, payment details. You can use that information for verifying the payment.
Get an access token
First we need to have an oAuth token from paypal. For this we need to do a POST to https://api.sandbox.paypal.com/v1/oauth2/token (sandbox url) passing our PayPal app's client Id and Secret.
Details of the HttpClient object I used in C#:
DefaultRequestHeaders.Accept: application/json
DefaultRequestHeaders.AcceptLanguage: en_US
DefaultRequestHeaders.Authorization: AuthenticationHeaderValue of Basic scheme, parameter of Base64String of bytes encoded from (clientId:clientSecret).
The response will have the property access_token which has the access token we want to pass in the next request to get the status of the transaction. For more details on getting access token refer: https://developer.paypal.com/docs/api/overview/#get-an-access-token.
Get sale details
Now to make the request for sale/transaction details as said here: https://developer.paypal.com/docs/api/payments/v1/#sale_get.
Do a GET passing the access token as Bearer token in the Authorization header.
And the unique transaction Id as parameter for the sale id. The response will have the property "state". Having the value "COMPLETED" ensures the transaction has gone successfully.

For PayPal Express Checkout, how long is the token valid for?

If a customer doesn't pay right away, can I store the token in a database and present it to them again at a later date (for example, 2 days later), so they can checkout again if they didn't complete it or didn't do it?
How to Create One-Time Payments Using Express Checkout
If the SetExpressCheckout request is successful, PayPal returns a token string in the Token response field. The default lifetime of this token is 3 hours
Hth...

No auth id assigned for intent=authorize

I think the ReSt authorization API is broken, I don't get back the ID for the auth object when doing POST /payment with intent=authorize.
Even calling GET /v1/payments/payment/{id} I don't get an auth id.
Here's the http log: http://pastebin.com/e1bEjfBF
As you can see I get "related_resources":[{"authorization":{"create_time"... but there is no id.
The pastbin sample shows the lookup of a payment resource that has not been approved yet.
Generally, for a PayPal Payment in Rest, you will have to:
Create a PayPal payment (POST payment request to https://api.sandbox.paypal.com/v1/payments/payment)
Redirect the buyer to the returned Approval_URL (usually something like https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=)
Upon return of the buyer to the return_url you specified in step 1, execute the payment (POST the PayerID to https://api.sandbox.paypal.com/v1/payments/payment/PAY-xxxx/execute/)
When you now lookup the Pay-Key, you should see the state of the Pay-Key as "approved", included buyer details, an Authorization TXN-ID and authorization state of "Authorized".
The next step would be to call the appropriate HATEOAS links to capture, void or reauthorize the authorization.
I've uploaded a sample flow to http://pastebin.com/JWG8Gzuv
You can also refer to the developer documentation located under https://developer.paypal.com/webapps/developer/docs/integration/direct/capture-payment/

How can I revoke a token using PayPal API

I have a website with two payment processors:
The other processor have an API call to invalidate a token, so if the user still didn't submit his payment info and I revoked his pending payment token -> he'll get an error.
There's a scenario where a (crazy) user can pay using both payment gateways:
1. The user starts a request to paypal
2. The user starts a request to other processor
3. He completes the payment with other processor
4. He then completes the payment with paypal
As I can see it, only revoking the paypal token can solve this condition.
If so - does anyone know how to do it programmatically?
Note: Any situation where two transactions are completed successfully is unacceptable (so refund/cancel and similar is not a solution)
I'm assuming you're using the (popular) express checkout API, and that the situation you're describing is AFTER you've issued a SetExpressCheckout but BEFORE you issued the DoExpressCheckoutPayment.
In that case, as you already redirected the shopper to the PayPal site, it's out of your hands and there's no API to revoke the token. However, there's a simple solution to your case. Even if the shopper approved the transaction at PayPal, you can still ignore the redirect and NOT issue a DoExpressCheckoutPayment request. In this case, the captured funds from his account (which you never got), will be returned to him 3 hours after the initial SetExpressCheckout was issues.
Don't forget to issue a proper notification to the user.