Count active subscriptions with PayPal API? - php

I need to use PHP to count the number of active subscriptions in my PayPal account (people subscribed to my service, not the counts of services I'm subscribed to).
Does anyone know how to do this or can point me in the right direction?
I can't find any documentation that allows you to see a list of your active subscriptions via the API, but I'm assuming that PayPal has this option and I'm just missing it...

This option cannot be found because it's apparently not available:
https://github.com/paypal/PayPal-REST-API-issues/issues/5

Apparently you cannot get a list of subscriptions regardless the status for the time being, as you can see here https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions there is no such feature available so let's hope Paypal adds it in the future.
However if you are storing the subscription ids in a database then you can loop them and foreach subscription id you can get the details of the subscription https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_get and check its status and finally display only the ones with an active status.

https://www.paypal.com/billing/api/orchestrator/subscriptions?data=%7B%22total_required%22%3Atrue%2C%22sort_order%22%3A%22desc%22%2C%22page_size%22%3A%2220%22%2C%22page%22%3A%221%22%2C%22plan_ids%22%3A%22P-123456789ABCDE%22%2C%22statuses%22%3A%22ACTIVE%22%2C%22tab%22%3A%22all%22%7D
Just pass a query string like:
{"plan_ids":"P-123456789ABCDE","statuses":"ACTIVE"}
You can GET this, and specify a page size. It seems the max is 20, but you can change the page number too.
Change the plan_ids parameter that I have as "P-123456789ABCDE" to your plan ID and you'll get a JSON response. I'm sure this isn't advertised, but I found it digging through the PayPal site.

There doesn't appear to be a direct way to list all of your subscriptions, but you can use the Transaction Search API to retrieve a list of your transactions (one month at a time, max 500 results per page) and grab the paypal_reference_id of each transaction object, which will be a valid subscription ID if the paypal_reference_id_type is "SUB".
Here's an example of the GET URL, which requires an Oauth token:
https://api-m.sandbox.paypal.com/v1/reporting/transactions?start_date=2022-07-01T00:00:00-0700&end_date=2022-07-31T23:59:59-0700&fields=all&page_size=500&page=1
Here's a simplified example of the response data:
{
"transaction_details":
[
"transaction_info":
{
"paypal_reference_id": "I-ABCDEFGHIJKL",
"paypal_reference_id_type": "SUB",
}
]
}
Once you've retrieved all of your subscription IDs, you can use the Subscriptions API to retrieve their details (such as its status) via an authenticated GET request:
https://api-m.sandbox.paypal.com/v1/billing/subscriptions/I-ABCDEFGHIJKL
Here's a simplified example of the response data:
{
"status": "ACTIVE",
}

Related

PayPal API refunds through PayPal plugin on WordPress / WooCommerce

I am currently using the current PayPal plugin https://wordpress.org/plugins/woocommerce-paypal-payments/
I have used the PayPal API to render more than one PayPal button on a page as the above plugin does not allow you to do this.
After the PayPal transaction is approved, it runs a PHP function that creates a WooCommerce order and fills in the data from the PayPal transaction such as the refund ID and setting the correct payment gateway etc. This all goes through great, but when it comes to refunding with the above plugin it fails.
I have compared the CSV files from both the API implementation and standard checkout process and both seem to be bringing in the same data.
I have done a bit of research and it seems that if an order is placed through checkout with the plugin, it creates its own order id, which may link back to the correct refund ID from the transaction. I have contacted their plugin support, but they have been unable to tell me.
Any help on this issue would be greatly appreciated!
When that plugin creates an order, an invoice_id and custom_id are set on these lines in the code.
The invoice ID is later used when doing a refund.
If you backtrack through that code doing the refund, it first makes use of a GET API call to the PayPal Order endpoint, which happens within here.
I highlight the particular line where this GET call depends on some meta information with the PayPal Gateway Order ID.
As an aside, this refund process is not well implemented by this WooCommerce plugin. Refunds are ultimately done using a capture ID, and should not rely on the Orders endpoint being accessible to provide a GET response that includes that capture ID. It works well enough so long as the PayPal Orders endpoint retains a record of that Order ID (which is not forever, as it's not an accounting value), but this is wrong to rely on. Instead, the Capture ID (eq. to the PayPal transaction ID) is what should be stored at transaction completion/capture time (as meta), and that stored meta value can then later be directly used to use the v2/payments refund, with no GET API request to the Orders API endpoint. The Orders API endpoint is only meant to be used during checkout approval, it is incorrect to be relying on it for anything once an order capture is successfully completed.

PayPal webhook: How to indentify the transaction related to webhook event

I have integrated a smart button checkout functionality in a marketplace where anybody can sell/buy items from anybody.
I also have successfully installed a webhook listener that gets notified if a refund of payment has been issued.
But in the body of the refund event received, I am failing to find information WHICH payment/transaction has been refunded.
By reading the event with
file_get_contents('php://input');
I will get the JSON encoded event details like this:
{
"id":"WH-3WS24689NP236083V-89P84301TC0576916",
"event_version":"1.0",
"create_time":"2020-07-10T15:36:33.720Z",
"resource_type":"refund",
"resource_version":"2.0",
"event_type":"PAYMENT.CAPTURE.REFUNDED",
"summary":"A EUR 7.89 EUR capture payment was refunded",
"resource":{
"seller_payable_breakdown":{
"total_refunded_amount":{
"value":"7.89",
"currency_code":"EUR"},
"paypal_fee":{
"value":"0.15",
"currency_code":"EUR"
},
"gross_amount":{
"value":"7.89",
"currency_code":"EUR"},
"net_amount": {
"value":"7.74",
"currency_code":"EUR"
}
},
"amount":{
"value":"7.89",
"currency_code":"EUR"
},
"update_time":"2020-07-10T08:36:00-07:00",
"create_time":"2020-07-10T08:36:00-07:00",
"links":[
{"method":"GET","rel":"self","href":"https://api.sandbox.paypal.com/v2/payments/refunds/3TF6899507696873K"},
{"method":"GET","rel":"up","href":"https://api.sandbox.paypal.com/v2/payments/captures/5U107751JJ334642K"}
],
"id":"3TF6899507696873K",
"status":"COMPLETED"
},
"links":[{
"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-3WS24689NP236083V-89P84301TC0576916",
"rel":"self",
"method":"GET"},{
"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-3WS24689NP236083V-89P84301TC0576916/resend",
"rel":"resend",
"method":"POST"}
]
}
So I get the data. But within the data I can not find any information like a "transaction id", "order id" or similar which I could use to look up in the DB if it matches the capture id (from capture order) of a previous order.
What do I need to do to get the information I need? Or am I looking in the wrong place/for the wrong field?
In case I need to auth the request first and make another request to get more data, I would be very grateful for a FULL example (or link to an example) in PHP as I can not make sense of the Paypal documentation on webhooks.
EDIT: It seems that in one of the links (in the event above), the capture ID (which is the same as the transaction id txn) of the original payment is "hidden" in one of the links providing endpoints. In this case: 5U107751JJ334642K
I can only shake my head at Paypal's way of making things incredible difficult to achieve. How can you NOT have a dedicated field with the id of the original transaction in a refund message?
Welcome to the wonderful world of Hypermedia as the Engine of Application State (HATEOAS [emphasis added…])!
The purpose of which is to give your application the information needed to discover and navigate to / execute related resources / actions dynamically. To that end, each API response or webhook payload contains a list of links.
As you have already discovered, in the present case, those link back to the parent resource, i.e. the refunded capture, via the up relationship.
While it may be tempting to extract the capture ID straight from the href, it might be safer to actually follow that link. You will receive the original capture response from which you can either grab the capture id or continue following the up link to get to the authorization.
You can find a little more information on PayPal's HATEOAS implementation on https://developer.paypal.com/docs/api/reference/api-responses/#hateoas-links. Those rel types that are standardized are documented on https://www.iana.org/assignments/link-relations/link-relations.xhtml#link-relations-1. For example, the description of rel="up" is "refers to a parent document in a hierarchy of documents".

Stripe : Specify Specific Card for Subscription

I have set up subscription based website that allows people to have multiple subscriptions. I decided to go with Stripe for payment and card processing. It took very little time to get it integrated into my Symfony2 project. I was able to create subscriptions, customers, and add cards within a couple of hours. Then I ran into an issue. If a customer has multiple cards, I wanted to be able to allow them to choose which card they wanted to use when they create a new subscription. It sounded easy. After 2 days and about 30 hours of combing through their documentation I have to say that I cannot figure out how to get this to work.
The way I have this set up is that when the customer creates a card I store the "card id" in my database along with the brand. This just makes it easy to load details on the server side when the page is being requested. The customer creating the new subscription sees their cards and choose which one they want to use for the new subscription. This is passed to my php script via AJAX to create the new subscription. However, when I try to use a specific card, I am getting a 400 error indicating that the "card id" is not a token. I know that it is not a token since the token was used to add the card to the customer account but how in the world do I specify the exact card that the customer wants to use?
NOTE: Using an a new token creates another instance of the card.Not an option.
PHP:
require_once('../stripe-php/init.php');
//Set Secret API Key
\Stripe\Stripe::setApiKey("sk_test_XXXXXXXXXXXXXXXXXXXXX");
//Retrieve Customer
$cu = \Stripe\Customer::retrieve($_POST['customer_id']);
//Create Subscription using saved customer "card id"
$createSubscription = $cu->subscriptions->create(array("plan" => $_POST['sub_option'], "source" => $card));
POSTED TO STRIPE:
plan: "500-2016"
source: "card_xxxxxxxxxxxxxxxxxxxxx"
STRIPE ERROR: TYPE 400
error:
type: "invalid_request_error"
message: "No such token: card_xxxxxxxxxxxxxxxxxxxxxxx"
param: "source"
I got a reply from Stripe support on this: it is not possible for one Customer to have subscriptions with different payment sources. All invoices for subscriptions are always billed to the current default_source for the Customer. So if you change the default as Giles Bennett suggested, you'll be changing it for all subscriptions, regardless of what the default was at time of creation.
If you need one user to have subscriptions with more than one source, you need to create multiple stripe Customer objects for that user, with a different default_source for each.
Since I have not received any input from SO or Stripe, I have somewhat came to the conclusion that this cannot be done. I found a similar question on a different forum that ended with the results being - No Response From Stripe - and that this cannot be done. Though the Stripe documentation does not hit on this subject it does appear that a Subscription can only be charged to the default card. There is no "Card" object for subscriptions as there is for a "Charge".
I realise this thread is quite old, but having come across it whilst trying to answer the same question myself, this solution may be of use to those who come along afterwards.
The Stripe API says that the "source" parameter for the API call to create a new subscription is optional - if ommitted, then it will default to the customer's default card. If included, then it can only be a token (ie. a new card) or a dictionary entry (again, for a new card, just not tokenised).
The solution could be to update the customer's default source first. Using Cartalyst through Laravel, as we are :
$customer = Stripe::customers()->update( "customer_id", [
'default_source' => "card_id"
]);
You can then proceed to add your subscription as normal - the newly-defaulted card will be assigned to it. If needs be (depending on your application) then you may also wish to save the previous default card ID to a variable first, to then allow you to set it back to being the default card after your new subscription.
I hope that helps.

How to get paypal sale transactions

I'm trying to pull in orders from paypal into my database. When I say orders, I mean orders from paypal buttons we have in various places.
I've dove into the REST API, but I don't see any API for searching for / listing transactions. I see a list of payment Resources, but that comes back with count 0.
I also see Sale Transactions in the API but that asks for a single transaction ID.
Is there a way I can periodically get transactions? I know this is possible because we use a tool called Shipstation that grabs new orders from Paypal and brings them into their system.
Thanks!
You can use REST APIs to do what you are wanting to do. You can use
GetPaymentList to do this. This is sample code from the PayPal Github PHP homepage. You will need to install and use the PayPal PHP SDK.

How do I identify orders with the Google Checkout Notification API (using PHP)?

I am using the Google Checkout API to code a simple store. I have gotten as far as letting the user select items, edit the cart, and checkout/pay with Google Checkout. The notification API (with XML) is being used to read notifications sent by Google after receiving orders. How can I connect the order notifications with the orders information in my SQL database? Can I send an "order ID" or something like that to Google with the initial order? I have coded that portion (ordering) with the HTML API.
Thanks in advance!
When an order is placed, a notification is made giving you a serial number for the order. You need to store this serial number in your database against whatever internal order number you have, so that you can use the serial number to refer to the order with Google Checkout via the Notification API.
No. Notification and Polling are two separate concepts.
Notification is when Google Checkout sends you info as it occurs, and Polling is when you send a request for sale details at some time in the future.
Documentation for Polling is lacking on-line. That is why you - and I - have not found the answer.
Google sends an e-mail when a sale is made (or when something goes wrong with a payment), and it stores some detail in your dashboard. You can use the date or the number to Poll for the rest of the details. Exactly how to do that is lacking in the on-line documentation.
Use the merchant-private-data field to pass any custom data about your order.
When you get back the notification, read the custom info from the merchant-private-data field.
See this answer for a solution to a similar issue.

Categories