Paypal v2 API how to get transaction data and also how to make a refund - paypal

My problem is as follows:
I have a business paypal account where I have a list of transactions made by my clients (buying products on my webpage). I store their orders info via paypal IPN which only sends me the transaction ID of the order. So I store this transaction ID on my database among other basic data.
Now I need 2 things:
Retrieve the transaction data via php code.
Make refunds of any transaction also via php code.
I see Paypal API v2 is the recommended as the v1 is gonna be abandoned. I'm using Checkout-PHP-SDK:
https://github.com/paypal/Checkout-PHP-SDK
But I'm facing problems only trying to get any transaction data. I read that in order to get the data i cannot use the transaction ID but the order ID instead. But how can use an order ID that I ignore?, because from paypal IPN I only receive transaction ID and that's only what I have. So how can I get the order id from this transaction id?. I know I'm probably confusing terms so sorry in advance.

When you capture an order, the immediate API response already contains all information about the transaction -- including the transaction ID at purchase_units[0].payments.captures[0].id. There is no need to use the old IPN service. Your integration should not depend on IPN in any way, that is bad design.
For refunds, use that transaction (capture) id with the v2/payments API

Related

How to get Order ID of a subscription payment from a Transaction from paypal API

I have a problem connecting subscription payments in paypal with their respective orders.
In a nutshell, the initial payment for the subscription is made on an order.
Once the user pays, the order is approved and I get this information from the paypal API:
{"id":"2M9235603X788581X","intent":"CAPTURE","status":"APPROVED","payment_source":{"paypal":{"email_address":"email_address","account_id":"8XHXZUT5Y3CVS","name":{"given_name":"John","surname":"Doe"},"address":{"country_code":"US"}}},"purchase_units":[],"payer":{"name":{"given_name":"John","surname":"Doe"},"email_address":"email_address","payer_id":"8XHXZUT5Y3CVS","address":{"country_code":"US"}},"create_time":"2023-02-13T17:24:46Z","links":[{"href":"https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/2M9235603X788581X","rel":"self","method":"GET"},{"href":"https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/2M9235603X788581X","rel":"update","method":"PATCH"},{"href":"https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/2M9235603X788581X\/capture","rel":"capture","method":"POST"}]}
Right of the bat the data is incomplete, missing crucial information such as fees and transaction details. So next best thing is to get the data on the webhook.
When the payment goes through an event is triggered "PAYMENT.SALE.COMPLETED", which sends this info to my server:
{"id":"WH-6SE66006R98946535-7F814879YL577135N","event_version":"1.0","create_time":"2023-02-13T17:25:09.906Z","resource_type":"sale","event_type":"PAYMENT.SALE.COMPLETED","summary":"Payment completed for EUR 39.37 EUR","resource":{"billing_agreement_id":"I-0HN4N0KTWLMP","amount":{"total":"39.37","currency":"EUR","details":{"subtotal":"39.37"}},"payment_mode":"INSTANT_TRANSFER","update_time":"2023-02-13T17:25:03Z","create_time":"2023-02-13T17:25:03Z","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","transaction_fee":{"currency":"EUR","value":"1.76"},"protection_eligibility":"ELIGIBLE","links":[{"method":"GET","rel":"self","href":"https://api.sandbox.paypal.com/v1/payments/sale/036421861N8145017"},{"method":"POST","rel":"refund","href":"https://api.sandbox.paypal.com/v1/payments/sale/036421861N8145017/refund"}],"id":"036421861N8145017","state":"completed","invoice_number":""},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-6SE66006R98946535-7F814879YL577135N","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-6SE66006R98946535-7F814879YL577135N/resend","rel":"resend","method":"POST"}]}
From the billing agreement ID (which is the subscription ID) I can get the transactions, based on a time period:
{"transactions":[{"status":"COMPLETED","id":"036421861N8145017","amount_with_breakdown":{"gross_amount":{"currency_code":"EUR","value":"39.37"},"fee_amount":{"currency_code":"EUR","value":"1.76"},"net_amount":{"currency_code":"EUR","value":"37.61"}},"payer_name":{"given_name":"John","surname":"Doe"},"payer_email":"sb-wi93p1551674#personal.example.com","time":"2023-02-13T17:25:03.000Z"}],"links":[{"href":"https://api.sandbox.paypal.com/v1/billing/subscriptions/I-0HN4N0KTWLMP/transactions?start_time=2023-02-01T07%3A50%3A20.940Z&end_time=2023-02-28T07%3A50%3A20.940Z","rel":"SELF","method":"GET"}]}
Now why it requires start and end date even though the filter is the agreement ID, I couldnt tell you, however here I can see the fees and since the event "PAYMENT.SALE.COMPLETED" has been triggered I can be sure that the payment has went through.
All thats left is for me to connect the transaction with the order.
But how?
There is no direct connection between the order and the transaction, no ID specified and nothing shown in the approved order.
How can I connect the transaction ID with the Order ID so I can have a proper confirmation and extract the fees?
I`ve tried direct capture, pulling the data from the API and setting up webhook for all payment and subscription events, yet nothing I've seen provides the required information.
SOLUTION:
So for any future developer that stumbels on this problem here is my advice and solution.
Make sure that you conform to the Paypal API and create reference records with their Subscription ID and transaction ID.
Now the tricky part is getting the transaction right away, so the user doesnt have to wait to long for a confirmation.
The way I`ve done this is after the subscription is created and the order approved, I send the relevant data to the server and using the Subscription ID I keep sending requests to get all transactions for it using this endpoint: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_transactions
I do this request with a while(){} cycle, for 5 max attempts with 2 seconds of sleep period between requests, since the transaction is not shown for the subscription right away.
After I get it I create the reference record and if the subscription transaction has the proper status, I save it as finished.
On the webhook, when receiving the "PAYMENT.SALE.COMPLETED" event, you need to check if the transaction reference is already created and if not, create it.
This will server you for any future payments (since its a subscription)
Hope this helps
In your example, the subscription ID is I-0HN4N0KTWLMP and the transaction ID of the first payment (sale/capture) is 036421861N8145017. (I don't know where the order ID 2M9235603X788581X is coming from; PayPal subscriptions do not use Order IDs, those are for one-time payments)
With the subscription ID you can get its details with a simple GET call: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_get , no date ranges are needed.
For details on the actual payment, such as fees, either of the payments API versions may work with that ID:
V2 capture get: https://developer.paypal.com/docs/api/payments/v2/#captures_get
Older V1 sale get: https://developer.paypal.com/docs/api/payments/v1/#sale_get
Listening for the webhook event PAYMENT.SALE.COMPLETED is the correct general solution for receiving a server-side notification of both the initial and future payments.
If you need your own "user" or similar ID for reconciliation, set custom_id when creating the subscription.

How to find paypal buyer order id in paypal official page

I have tried to find overtime for get paypal order id in paypal page but nothing found yet. Can anybody tell find buyer order id from paypal page
Order IDs from the v2/checkout/orders API are only used to keep track of a checkout attempt for approval. They are not persisted in the PayPal system afterward, and you cannot find them in any account views or reports. They are not useful for any accounting once a transaction has been captured, that is not their purpose.
When a v2/checkout/order is captured, the PayPal transaction ID will be in the capture response at purchase_units[0].payments.captures[0].id. This ID is the one that should be persisted, and will be useful to reference in account views and reports.
You can also store your system's own unique ID as part of any transaction. The invoice_id at order creation time exists for this. Make sure it is unique (never before used for a previously successfully captured transaction). For a non-unique field that can store arbitrary data, use custom_id.

Integrating Paypal Payment and Invoicing APIs

I have been manually issuing invoices to charge my clients for services using Paypal.
Now I am creating an interface to allow them to purchase the services automatically on my website.
I also want to show them a history of their purchases. However, I cannot show a history of paid invoices using the Transaction Search API; I need to use the Invoicing > Search Invoices API.
I have used the Paypal Payments API to manage the payment side of new products, which now correctly produces an itemised transaction and allows the customer to checkout. But this does not produce an invoice.
How can I simultaneously produce an invoice (i.e which can be retrieved by the Invoicing API to show previous payments) and allow the customer to pay it? It seems like the Invoicing API works around the idea of sending an invoice to client by email, but this is unnecessary. I want them to pay it immediately (and already have the Payment API setup for this).
So what would a useful workflow be?: Use my Paypal Payment API to receive and authorise the payment, and on authorisation, use the Invoicing API to produce an invoice which reflects this and then updates the invoice status to paid? Or am I missing something easier here?
The Invoicing API is not meant to be mixed or used with any other API. It is for generating invoices to be sent by email or in link form.
General ecommerce payment processing (without invoice links) is entirely separate, there is no crossover. You should ensure you are using the current v2/checkout/orders API to receive new payments, not older v1 APIs.
As far as displaying a list of previous purchases to your customers, you shouldn't reply on PayPal for this (except perhaps in the case of invoices since this is part of the point of offloading invoice management to PayPal). But for normal web purchases, PayPal is not a database -- it is a payment processing service. Keep track of all your own order information, and simply store PayPal transaction IDs when they complete for your own accounting records -- but the ID you reference with the customer should be your own unique order ID, which you can pass to PayPal in your purchase_units[0].invoice_id when you create an order for checkout approval.

Retrieve transaction ID via rest API

My application uses PayPal java library to make payments. Everything works fine but I can't understand one thing. What exactly is transaction code? Let's say I make a payment and then approve it. As a result I receive the JSON object which has an ID (PAY-*) and transactions->related resources->sale->ID. Both of them I store in the DB in order to show later to user (in case he wants to refund the money). But if I see these payments from PayPal customer portal, in the descriptions of payment I see non of these ID's.. Transaction code is totally different! So which one of them should I store?
Thank you in advance
PayPal generally uses a transaction ID. It's a 16 character alphanumeric string. This will appear in both your API response and the PayPal site. Assuming REST is like Classic, the Transaction ID is how you will reference the payment for any future operations (capture, refund, etc).
Please note that if you're using Express Checkout (where the customer pays via PayPal account) they will have their own transaction ID for the exact same transaction.

PayPal Express Customer Checkout Transaction ID

I'm using PayPal Express checkout and I'm trying to display to the customer their transaction id at the end of the checkout process on the thank you page.
I'm currently pulling back:
PAYMENTREQUEST_0_TRANSACTIONID
Which is the transaction id that is logged in my business account. However the transaction id on the email sent to the customer is different to this id that is being returned.
I'm using this API: https://developer.paypal.com/docs/classic/api/merchant/SetExpressCheckout_API_Operation_NVP/
The documentation states
"(Optional) Transaction identification number of the transaction that was created. You can specify up to 10 payments, where n is a digit between 0 and 9, inclusive.
Note This field is only returned after a successful transaction for DoExpressCheckout has occurred.
TRANSACTIONID is deprecated since version 63.0. Use PAYMENTREQUEST_0_TRANSACTIONID instead. "
I'm also using
PAYMENTREQUEST_0_INVNUM
Which is very helpful and lets me put my order reference number into the main body of the email that the customer receives, but I'd also like their transaction id, so that if they send a query through this can be logged in a field in the database and cross referenced against the order with just the transaction id.
Any help would be appreciated!
Thanks
PayPal assigns different transactions to the buyer and the seller. I'm not exactly sure why, but I know they do.
If a customer gives you their transaction ID, though, you CAN find it in your PayPal account by doing a search through paypal.com or via the TransactionSearch API.