Last active
November 21, 2022 13:19
-
-
Save LeCoupa/85e71a30eb51d2eae76b to your computer and use it in GitHub Desktop.
Meteor Paypal REST API --> https://github.com/LeCoupa/awesome-cheatsheets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This gist illustrates how to create and execute a payment with Paypal using their REST API. | |
# For additional informations, check the documentation: https://developer.paypal.com/docs/api/ | |
# Note 1: I assume that you have already created a developer account for Paypal and an application. | |
# To test that your code is working, use the sandbox accounts. | |
# https://developer.paypal.com/webapps/developer/applications/accounts | |
# Note 2: we will not use the Paypal REST API SDK package for Node.js | |
# https://github.com/paypal/rest-api-sdk-nodejs | |
# The following code must be only run on the server! | |
# 1. Create your paypal configuration object. | |
@paypalConf = | |
host: "api.sandbox.paypal.com" | |
clientId: "pHQcZ1cH0lnX5Mub4MGzo_-FH6witB3_2zuRYgvUFxMHFH6wiAe3zCRDqatu3" | |
clientSecret:"Xk7-EDJqERAU5up6wjeVoRE6WM2OoIsUT3ouxVRKUmjX38b4k0-q6t_UHei" | |
# 2. Create two collections to save our payments and the Paypal tokens. | |
@PaypalPayments = new Meteor.Collection 'paypal_payments' | |
@PaypalTokens = new Meteor.Collection 'paypal_tokens' | |
# 3. Create the three methods to: | |
# - Get a valid token to make API calls. (retrieve a new one if invalid) | |
# - Create a payment | |
# - Execute a payment. | |
Meteor.methods | |
'getPaypalToken': -> | |
isTokenValid = 0 | |
token = PaypalTokens.findOne({ timestamp: { $exists: true } }, | |
{ sort: { timestamp: -1 } }) | |
if token? | |
isTokenValid = Math.ceil((new Date().getTime() - token.timestamp) / 1000) | |
# is the token invalid? | |
if isTokenValid is 0 or isTokenValid > token.expires_in | |
auth = paypalConf['clientId'] + ':' + | |
paypalConf['clientSecret'] | |
token = EJSON.parse( | |
Meteor.http.post('https://api.sandbox.paypal.com/v1/oauth2/token', | |
headers: | |
'Accept': 'application/json' | |
'Accept-Language': 'en_US' | |
auth: auth | |
params: | |
'grant_type': 'client_credentials' | |
).content) | |
token['timestamp'] = new Date().getTime() | |
# we insert the new valid token to retrieve it later | |
PaypalTokens.insert token | |
return token | |
'createPaypalPayment': (product) -> | |
token = Meteor.call 'getPaypalToken' | |
payment = | |
intent: 'sale' | |
payer: | |
payment_method: 'paypal' | |
redirect_urls: | |
return_url: 'http://localhost:3000/dashboard/payment/paypal/execute' | |
cancel_url: 'http://localhost:3000/dashboard' | |
transactions: [ | |
item_list: | |
'items': [ | |
'name': product.name, | |
'price': product.price, | |
'currency': 'USD', | |
'quantity': 1 | |
] | |
amount: | |
total: product.price | |
currency: 'USD' | |
description: product.description | |
] | |
res = Meteor.http.post 'https://api.sandbox.paypal.com/v1/payments/payment', | |
headers: | |
Authorization: 'Bearer ' + token.access_token | |
'Content-Type': 'application/json' | |
data: payment | |
res.data['userId'] = @userId | |
# we insert the payment details (for the payment id during execution) | |
PaypalPayments.insert res.data | |
return res.data | |
'executePaypalPayment': (payerId) -> | |
payment = PaypalPayments.findOne({ userId: @userId }, | |
{ sort: { 'create_time': -1 } }) | |
token = Meteor.call 'getPaypalToken' | |
url = 'https://api.sandbox.paypal.com/v1/payments/payment/' + | |
payment.id + '/execute' | |
res = Meteor.http.post url, | |
headers: | |
Authorization: 'Bearer ' + token.access_token | |
'Content-Type': 'application/json' | |
data: | |
payer_id: payerId | |
payment = res.data | |
payment['userId'] = @userId | |
if payment.state in ['approved' , 'pending'] # Be careful, in production the payment state is "pending" | |
# we insert the sucessful payment here | |
PaypalPayments.insert payment | |
return if payment.state is 'approved' then true else false | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The following code must be accessible to the client. | |
# 4. We configure Iron Router to handle the different payment steps. | |
# For more informations: https://github.com/EventedMind/iron-router | |
Router.map -> | |
@route 'DashboardRoot', | |
path: '/dashboard/' | |
@route 'DashboardPaymentPaypalExecute', | |
path: '/dashboard/payment/paypal/execute/' | |
# 5. Templates Events. | |
Template.DashboardRoot.events | |
'click .buy-product': -> | |
product = | |
name: 'product name' | |
description: 'production description' | |
price: 30.00 | |
Meteor.call 'createPaypalPayment', product, (err, res) -> | |
window.location.replace res.links[1].href | |
Template.DashboardPaymentPaypalExecute.created = -> | |
payerId = window.location.search.split('PayerID=')[1] | |
Meteor.call 'executePaypalPayment', payerId, (err, res) -> | |
if res is true | |
console.log 'Your payment has been successfully executed.' | |
else | |
console.log 'Your payment has been refused.' | |
Router.go 'DashboardRoot' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- 6. The Dashboard Template --> | |
<template name="DashboardRoot"> | |
<span class="buy-product">Buy this product</span> | |
</template> | |
<!-- 7. The Dashboard Payment Paypal Execute Template --> | |
<template name="DashboardPaymentPaypalExecute"> | |
<span class="loading">Wait a few seconds, we are processing your payment.</span> | |
</template> |
Meteor is a full-stack framework for building top-quality web apps in a fraction of the time, whether you're an expert developer or just getting started. Paypal API is a Payment Gateway API for payments in your application. It can be used to accept payments from your app or website. Learn how to accept payments from your app using our REST API. In this article, we will learn how to use this API with Meteor. We will create two example apps, one for doing payments and the other for logging in.
Follow these instructions:
https://mmcgbl.com/api-development/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great gist!
I am attempting to test it out with an app I am developing and cant seem to get it to work however. The first thing I did was convert the code from coffee script to javascript at http://js2coffee.org/ . I then created all the necessary files on the client and server. However when I click the "buy this product" link I get the following errors;
client:
Exception in delivering result of invoking 'createPaypalPayment': TypeError: Cannot read property 'links' of undefined
at http://localhost:3000/client/views/paypal/DashboardRoot.js?c9ac527f12033c2ff0d64317caed7e262304d1b0:10:41
(this is the line in question) -> return window.location.replace(res.links[1].href);
server:
Exception while invoking method 'createPaypalPayment' TypeError: Cannot call method 'post' of undefined
at Meteor.methods.getPaypalToken (app/server/paypal_config.js:30:39)
(this is the line in question) -> token = EJSON.parse(Meteor.http.post('https://api.sandbox.paypal.com/v1/oauth2/token', { ...
Any idea what might be causing this?
Thanks.
_edit_*
Found the issue, I needed to include the http package in my project
mrt add http resolved the problem.