Node.js에서 Paypal REST API 연동하기

2017. 6. 21. 16:27서버 프로그래밍

가장 괜찮은 레퍼런스는 다음 포스팅이다.

샘플 데이터베이스 구성에서부터 Paypal 연동 및 결과 처리까지 하나의 사이클에 대한 전체 예제라고 큰 도움이 된다.

결제 중간에 페이팔 페이지로 갔다가 다시 돌아와야하므로 callback URL등의 정보를 세션을 이용해서 처리해야 한다.


Nodejs PayPal Integration

http://www.codershood.info/2016/07/19/nodejs-paypal-integration/

const self={
    isUserExists:function(data,callback){
    	var response={};
		Mongodb.onConnect(function(db,ObjectID){
			db.collection('users').findOne(data,function(err, result){
				if(result != null ){
					response.process = "success";
					response.isUserExists = true;				
					response.id = result._id;
					response.name = result.name;
				}else{
					response.process = "failed";
					response.isUserExists = false;
				}					
				callback(response);
			});
		});
	},
	insertPayment:function(data,callback){
		var response={};
		Mongodb.onConnect(function(db,ObjectID){
			db.collection('payments').insertOne(data,function(err, result) {
				if(err){
					response.isPaymentAdded = false;
					response.message = "Something went Wrong,try after sometime.";
				}else{
					response.isPaymentAdded = true;
					response.id=result.ops[0]._id;
					response.message = "Payment added.";
				}
				callback(response);	
			});
		});
	},	
	getProductInfo:function(data,callback){
		var response={};
		Mongodb.onConnect(function(db,ObjectID){
			data._id = new ObjectID(data._id);
			db.collection('products').findOne(data,function(err, result){						

				if(result != null ){
					response.error = false;
					response.data = result;
				}else{
					response.error = true;
				}	
				callback(response);
			});
		});
	},
	getAllProducts:function(data,callback){
		Mongodb.onConnect(function(db,ObjectID){
			db.collection('products').find().toArray(function(err, result){
				callback(result);
				db.close();
			});
		});
	},
	payNow:function(paymentData,callback){
		var response ={};

		/* Creating Payment JSON for Paypal starts */
		const payment = {
			"intent": "authorize",
			"payer": {
				"payment_method": "paypal"
			},
			"redirect_urls": {
				"return_url": "http://127.0.0.1:81/execute",
				"cancel_url": "http://127.0.0.1:81/cancel"
			},
			"transactions": [{
				"amount": {
					"total": paymentData.data.price,
					"currency": "USD"
				},
				"description": paymentData.data.productName
			}]
		};
		/* Creating Payment JSON for Paypal ends */

		/* Creating Paypal Payment for Paypal starts */
		paypal.payment.create(payment, function (error, payment) {
			if (error) {
				console.log(error);
			} else {
		    	if(payment.payer.payment_method === 'paypal') {
		    		response.paymentId = payment.id;
		    		var redirectUrl;
		    		response.payment = payment;
		    		for(var i=0; i < payment.links.length; i++) {
		    			var link = payment.links[i];
		    			if (link.method === 'REDIRECT') {
		    				redirectUrl = link.href;
		    			}
		    		}
		    		response.redirectUrl = redirectUrl;
		    	}
		    }
		    /* 
		    * Sending Back Paypal Payment response 
		    */
		    callback(error,response);
		});
		/* Creating Paypal Payment for Paypal ends */		
	},
	getResponse:function(data,PayerID,callback){

		var response = {};
		
		const serverAmount = parseFloat(data.paypalData.payment.transactions[0].amount.total);
		const clientAmount = parseFloat(data.clientData.price);
		const paymentId = data.paypalData.paymentId;
		const details = {
			"payer_id": PayerID 
		};

		response.userData= {
			userID : data.sessionData.userID,
			name : data.sessionData.name
		};

		if (serverAmount !== clientAmount) {
			response.error = true;
			response.message = "Payment amount doesn't matched.";
			callback(response);
		} else{
			
			paypal.payment.execute(paymentId, details, function (error, payment) {
				if (error) {
					console.log(error);
					response.error = false;
					response.message = "Payment Successful.";
					callback(response);
				} else {

					/*
					* inserting paypal Payment in DB
					*/

					const insertPayment={
					    userId : data.sessionData.userID,
					    paymentId : paymentId,
					    createTime : payment.create_time,
					    state : payment.state,
					    currency : "USD",
					    amount: serverAmount,
					    createAt : new Date().toISOString()
					}

					self.insertPayment(insertPayment,function(result){

						if(! result.isPaymentAdded){
							response.error = true;
							response.message = "Payment Successful, but not stored.";
							callback(response);
						}else{
							response.error = false;
							response.message = "Payment Successful.";
							callback(response);
						};
					});
				};
			});
		};
    }
}


paypal-rest-sdk의 npm 매뉴얼도 도움이 된다. 다만, 다른 npm 매뉴얼에 비해 예제나 설명이 부족하게 느껴진다.

https://www.npmjs.com/package/paypal-rest-sdk


비슷한 스타일의 다른 레퍼런스도 있는데, 조금 지난 정보라 감안하고 참고해야할 듯

https://devblog.paypal.com/building-a-web-app-with-node-js-the-paypal-sdk/

https://devblog.paypal.com/building-a-web-app-with-node-js-the-paypal-sdk-part-2/

https://devblog.paypal.com/building-a-web-app-with-node-js-the-paypal-sdk-part-3/


아래는 페이팔 테스트 계정으로 연동하는 부분에 대한 참고 자료이다.

직접적인 도움은 되지 않지만 참고할만한 내용들이 있다.


[01] Paypal 을 붙여보자!

http://devlecture.tistory.com/entry/01-Paypal-%EC%9D%84-%EB%B6%99%EC%97%AC%EB%B3%B4%EC%9E%90

01. paypal의 테스트 ID만들고, 결제 창 띄워 보기

http://serpiko.tistory.com/462