Reputation: 8682
I have a Paypal Button setup with the following code:
paypal.Buttons({
createSubscription: function(data, actions) {
return actions.subscription.create({
'plan_id': 'P-PLANID'
});
},
onApprove: function(data, actions) {
// Somehow pass info to Webhook
}
}).render('#paypal-button-container');
Is there a way to have this integrate with a webhook I have setup with BILLING.SUBSCRIPTION.ACTIVATED
?
I just created the webhook but I am not sure how I connect my PayPal Buttons to it
Upvotes: 2
Views: 813
Reputation: 7781
My example isn't exactly a webhook per-se, but it works great for me. I put a call to a Firebase Cloud Function call in the onApprove
function like this:
paypal.Buttons({
createSubscription: function(data, actions) {
return actions.subscription.create({
'plan_id': 'P-PLANID'
});
},
onApprove: function(data, actions) {
const orderID = data.orderID;
let url = "myCloudFunction?orderID="+orderID;
//this will verify the purchase and complete order on back end
fetch(url);
//carry on with user experince
}
}).render('#paypal-button-container');
And then verify the purchase using the orderID
in my cloud function, and update my DB or whatever else i need to do like so:
const checkoutNodeJssdk = require('@paypal/checkout-server-sdk');
const functions = require("firebase-functions");
function environment() {
let clientId = process.env.PAYPAL_CLIENT_ID || 'yourClientID';
let clientSecret = process.env.PAYPAL_CLIENT_SECRET || 'yourClientSecret';
return new checkoutNodeJssdk.core.LiveEnvironment(
clientId, clientSecret
);
}
function payPalClient() {
return new checkoutNodeJssdk.core.PayPalHttpClient(environment());
}
exports.completeOrder = functions.https.onRequest((req, res) => {
const orderID = req.query.orderID;
let request = new checkoutNodeJssdk.orders.OrdersGetRequest(orderID);
let order;
try {
order = await payPalClient().execute(request);
console.log(order);
} catch (err) {
console.error(err);
res.send({response: "failed"});
}
if (order.result.status === 'APPROVED') {
//update DB or whatever else needs to happen to complete order
res.send({response: "success"});
} else {
res.send({response: "failed"});
}
});
You can also verify the subscription is active by passing a subscriptionID from the data object returned in the onApprove
function of the button to the cloud function. Use the following to verify the subscription:
async function verifySubscription(subscriptionID, callback) {
const authUrl = "https://api-m.paypal.com/v1/oauth2/token";
const subscriptionsUrl = "https://api.paypal.com/v1/billing/subscriptions/" + subscriptionID;
const clientIdAndSecret = "myClientID:myCLientSecret";
const base64 = Buffer.from(clientIdAndSecret).toString('base64')
fetch(authUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Accept-Language': 'en_US',
'Authorization': `Basic ${base64}`,
},
body: 'grant_type=client_credentials'
}).then(function(response) {
return response.json();
}).then(function(data) {
fetch(subscriptionsUrl, {
method: 'get',
headers: {
'Authorization': 'Bearer '+data.access_token,
'Content-Type': 'application/json'
},
}).then(function(response) {
return response.json();
}).then(function(subscriptionData) {
console.log("subscriptionData.status: ", subscriptionData.status);
if (subscriptionData.status === "ACTIVE") {
callback(true);
} else {
callback(false);
}
}).catch(function(error) {
console.log("couldnt verify subscription");
console.log(error);
callback(false);
});
}).catch(function() {
console.log("couldnt get auth token");
callback(false);
});
}
Upvotes: 0
Reputation: 30477
You need to subscribe to webhook events using the same app/client-id as you are using for the buttons. You can subscribe manually in the Developer Dashboard, or via an API call. Here is the documentation.
This comment in your code does not make sense:
// Somehow pass info to Webhook
Subscribing to webhook event notifications is a one-time, initial setup that you do somewhere else. It is not something you do from the buttons, and it will not call nor interact with the buttons in any way; webhooks are sent and processed later, asynchronously.
If you want to store some information as part of the subscription for later reconciliation (with the user who subscribed, for example, so your backend knows what to do when it receives a webhook) -- then you can set a custom_id
as part of the subscription creation.
Upvotes: 0