PayPal Docs are just awesome to read. ~Sahil
Quick Links:
@paypal/react-paypal-js
: Github"card": {"number": "4012888888881881", "expiry": "2028-03"
Card: 4012888888881881
Expiry 03/28
CSC: 888
ZipCode: 95833
City: Sacramento
State: California
/* eslint-disable @typescript-eslint/no-unused-vars */
// src: https://gist.github.com/romaad/cc588abf691ba1e29c4a853983de8eb1
const axios = require('axios');
const qs = require('qs');
const paypalApi = 'https://api-m.sandbox.paypal.com';
// PLEASE FILL THESE BEFORE RUNNING THE CODE ####
const clientId = '';
const clientSecret = '';
// We need this line to format the body in the expected way
// for 'application/x-www-form-urlencoded'
const payload = qs.stringify({
grant_type: 'client_credentials',
// Note: With `ignoreCache=true` a new token is issued ignoring the previously issued and still not expired token.
ignoreCache: true, // (default=false)
});
const headers = {
Accept: 'application/json',
'Accept-Language': 'en_US',
'content-type': 'application/x-www-form-urlencoded',
};
const auth = {
username: clientId,
password: clientSecret,
};
const config = {
headers, auth,
};
const main = async () => {
try {
const paypalSubscriptionId = 'I-B9YPX4SD1FX3';
const res1 = await axios.post(`${paypalApi}/v1/oauth2/token`, payload, config);
const { data } = await axios.get(`${paypalApi}/v1/billing/subscriptions/${paypalSubscriptionId}`, {
headers: {
Authorization: `Bearer ${res1.data.access_token}`,
},
});
console.log('data?', data);
} catch (error) {
console.log('error?', error.name);
console.log('error?', error.message);
}
};
main();
access_token
with axios// src: https://gist.github.com/romaad/cc588abf691ba1e29c4a853983de8eb1
const axios = require('axios');
const qs = require('qs');
const paypalApi = 'https://api-m.sandbox.paypal.com';
// PLEASE FILL THESE BEFORE RUNNING THE CODE ####
const clientId = '';
const clientSecret = '';
// We need this line to format the body in the expected way
// for 'application/x-www-form-urlencoded'
const payload = qs.stringify({
grant_type: 'client_credentials',
// Note: With `ignoreCache=true` a new token is issued ignoring the previously issued and still not expired token.
ignoreCache: true, // (default=false)
});
const headers = {
Accept: 'application/json',
'Accept-Language': 'en_US',
'content-type': 'application/x-www-form-urlencoded',
};
const auth = {
username: clientId,
password: clientSecret,
};
const config = {
headers, auth,
};
const main = async () => {
try {
const { data } = await axios.post(`${paypalApi}/v1/oauth2/token`, payload, config);
console.log('data?', data);
} catch (error) {
console.log('error?', error.name);
console.log('error?', error.message);
}
};
main();
We can set start_date and end_date like that -
Eric
(Thanks Eric)Link that may be helpful if you haven’t seen it (about a monthly renewal timing edge case):
No. It keeps the subscriptionId
same always (chatGPT).
We can choose from two options for the PayPal integration i.e,
OR
Users do this by hitting our slasher api, for e.g, /api/v1/podcast/activate-subscription and behind the scenes we’ll call activate-subscription api on paypal server.
We get an “approve-url” as result of the “activate-subscription” request and then we return that url to the user.
https://example.com/app/podcasts/SUBSCRIPTION-RETURN-URL/return?subscription_id=I-VDA50T7LKCFY&ba_token=BA-1Y6871089W3522241&token=1MM66374W7146800L
Thus we can collect subscription_id and check for that subscription status after every 5 seconds while the user is still on this page (it is generally successful instantly though). And we can let the user know the txn is successful by calling a simple txn status or subscription status API on our backend. That’s all.
Let me know what your and Damon’s preferences are, if possible please try communicating with Damon as these are minute details and don’t make much difference after the process is complete.
What are actual differences though in my view in the above two ways?
More or less, I am equally biased on each way of implementation. Thanks.
Also, I tested both ways thoroughly it works fine either way.
Login @ https://www.sandbox.paypal.com/signin
sb-xxxxxxxxxxxxx@business.example.com
sb-xxxxxxxxxxxxx@personal.example.com
Note - You should:
Account Settings
> Website payments
> Website Preferences
and enable both Auto return
and Payment data transfer
. For return url you may give https://slasher.tv/app/paypal/return-url
but it isn’t useful as you must definte the return url in each create-subscription
(POST /v1//billing/subscriptions) API call.cancel_url
as well as that would be helpful to know when the payment is failed.- return url = https://example.com/return
https://example.com/return?subscription_id=I-VDA50T7LKCFY&ba_token=BA-1Y6871089W3522241&token=1MM66374W7146800L
- cancel_url =https://example.com/cancel
https://example.com/cancel?subscription_id=I-7M0U6C9DWEL3&ba_token=BA-0WY1453654212191G&token=4CJ88294AB124721F
- return url = https://example.com/page/subpage
https://example.com/page/subpage?subscription_id=I-7M0U6C9DWEL3&ba_token=BA-0WY1453654212191G&token=8Y12132035380693N
- "cancel_url": "https://example.com/page/subpage"
https://example.com/page/subpage?subscription_id=I-7M0U6C9DWEL3&ba_token=BA-0WY1453654212191G&token=4CJ88294AB124721F
Docs - Payment Data Transfer: Click here
onApprove
on paypal-react compponent function is only called when txn is approved (i.e., successful)So, we have either of two options:
Transaction Search > List Transaction
in postman PayPal api collection.Subscriptions > Show subscriptions details
in postman PayPal api collection.subscriptions
and plans
in Selller Account (sandbox) like thatNow, you can use that button to toggle b/w group by product or group by plan view
Date: 29 August, 2023
Clientid:
AUv8rrc_P-EbP2E0mpb49BV7rFt3Usr-vdUZO8VGOnjRehGHBXkSzchr37SYF2GNdQFYSp72jh5QUhzG
ClientSecret:
EMnAWe06ioGtouJs7gLYT9chK9-2jJ--7MKRXpI8FesmY_2Kp-d_7aCqff7M9moEJBvuXoBO4clKtY0v
Account Settings > Account access > API access > Update > Manage REST API apps credentials
Image: 1/2
Image: 2/2
To be able to fetch transaction from my seller account I had to change this setting using my PayPal sandbox developer account
**
subscription_id
We can get a list of transactions made for a given subscription by using List transactions for subscription
API (we pass a subscription_id
as param) in postman. We can use this showing all the payment history for a given person if we store a subscription_id
for each user in the database.
Getting the subscription txns and their respective ids from the list of transactions we get by List transactions
REST API of postman collection
Source - API DOCS: Click here
Source - Docs: Click here
Other links to help you prorate:
When creating a subscription you can give the start_date
to set the start date and time for this subscription. Also, if you just want the subscription to start immeditely you can simply delete that field from the payload of the request and in the response you’ll see the current time automatically set by the paypal server.
status
field is not allowed at all. ~IMO Sahil(well tested).start_date
Please use this site to generate a free url which you can use to test webhook on paypal.
Webhooks simulator | Paypal: Click here |
Credit Card Generator, How to use Failed Cards, More 3DS Payments and More Test Accounts.
// Sahil Personal Account (Sandbox Details)
// const clientId = 'AZxr-cT_Indgclkxvqr_yUgFqWiYUJpHLmOKwrucdOseQsFzSrfsCRLaBNZKH9rT5RGCAFK4QgppxKGS'
// const planIds = {
// one: 'P-1U585596S70968643MONXJHI',
// three: 'P-3J697311GS257702PMONXJIQ',
// six: 'P-81C6483981287853TMONXJJQ',
// }
Things don't appear to be working at the moment. Please try again later.