By integrating Paypal with NetSuite, users can pay an invoice from the email.
Components :-
1.Email Template
2.HTML page to display payment
3. Suitelet to receive the post request from the payment
An email with payment button is send to the user. When the user clicks the button then the user redirected to suitelet page . Then user can see the bill details and then click the payment button. On clicking payment button the user will be redirected to payment screen. By entering card details user can pay the bill.
Suitelet:
/**
* @NApiVersion 2.x
* @NScriptType Suitelet
* @NModuleScope SameAccount
*/
/**
* Script Description
* This suitelet is to load HTML and recive post request
* HTML consists A form
*/
/*******************************************************************************
*
* Support Files
*
* *****************************************************************************
*
*
*
* $Author: Jobin & Jismi IT Services LLP $
*
* DESCRIPTION
* Paypal Integereation
*
* REVISION HISTORY Update:
*
*
*
******************************************************************************/
define(['N/file', 'N/url', 'N/search', 'N/runtime', 'N/record', 'N/https'],
function paypal(file, url, search, runtime, record, https) {
var main = {
dopost: function(datas, invoice, invoiceinternal) {
// var paymentdetails = main.getpaymentdetails();
log.debug("datas", datas);
var recordId = main.createpaypalrecord(datas, invoice, invoiceinternal);
// main.setpaypal(invoiceinternal, datas);
return recordId;
},
getpaymentdetails: function(data) {
var token = main.genaratetoken();
var paymenentdetails = main.fetchpayment(token);
return paymenentdetails;
},
fetchpayment: function(token) {
var authstr = 'Bearer ' + token;
log.debug("authstr", authstr);
var header = {
'Authorization': authstr,
'Content-Type': 'application/json'
};
var response = https.get({
url: 'https://api.sandbox.paypal.com/v1/payments/payment/PAY-0GY190188E592451DLLMDSEY',
headers: header
});
log.debug("paymenentdetails+resposne", response);
return response
},
createpaypalrecord: function(livedata, invoice, invoiceinternalid) {
var livedata = JSON.parse(livedata);
log.debug("livedata", livedata);
var paypalrecord = record.create({
type: 'customrecord_esw_47_papal_payment',
isDynamic: true
});
paypalrecord.setValue({
fieldId: 'custrecord_jj_payment_id',
value: livedata.paymentID,
ignoreFieldChange: true
});
paypalrecord.setValue({
fieldId: 'custrecord_jj_payerid',
value: livedata.payerID,
ignoreFieldChange: true
});
paypalrecord.setValue({
fieldId: 'custrecord_jj_inovice',
value: invoiceinternalid,
ignoreFieldChange: true
});
/* paypalrecord.setValue({
fieldId: 'custrecord_jj_payer',
value: "2",
ignoreFieldChange: true
});
paypalrecord.setValue({
fieldId: ' custrecord_jj_amount',
value: "2",
ignoreFieldChange: true
});*/
paypalrecord.setValue({
fieldId: 'custrecord_jj_orderid',
value: livedata.orderID,
ignoreFieldChange: true
});
paypalrecord.setValue({
fieldId: 'custrecord_jj_paymentmethod',
value: livedata.paymentToken,
ignoreFieldChange: true
});
paypalrecord.setValue({
fieldId: 'custrecord_jj_invoice',
value: invoice,
ignoreFieldChange: true
});
var recordId = paypalrecord.save({
enableSourcing: 'false',
ignoreMandatoryFields: 'false'
});
log.debug("recordId", recordId);
return recordId;
},
setpaypal: function(invoiceinternal, livedata) {
var invoicerecord = record.load({
type: "invoice",
id: invoiceinternal
});
invoicerecord.setValue({
fieldId: 'custbody_esw_paypal_invoiceid',
value: livedata.paymentID,
ignoreFieldChange: true
});
invoicerecord.setValue({
fieldId: 'custbody_esw_paypal_paidby',
value: true,
ignoreFieldChange: true
});
var recordId = invoicerecord.save({
enableSourcing: 'false',
ignoreMandatoryFields: 'false'
});
return recordId
},
onRequest: function(context) {
if (context.request.method === 'POST') {
var datas = context.request.parameters.datas;
var invoice = context.request.parameters.invoice;
var invoiceinternal = context.request.parameters.invoiceinternal;
var details = main.dopost(datas, invoice, invoiceinternal);
context.response.write("Success");
} else {
var invoice = context.request.parameters.invoice;
var fileid = main.getfileid();
var newhtml = main.gethtml(fileid, invoice);
log.debug("newhtml", newhtml);
context.response.write({
output: newhtml
});
}
},
getfileid: function() {
var bundleurl = "ESW-47 Paypal Integertion/";
try {
bundleurl = "ESW-47 Paypal Integertion/";
var fileObj = file.load({
id: bundleurl + 'JJ_HTML_MW_Form.html' // '13147'
});
} catch (e) {
bundleurl = "SuiteBundles/Bundle 189004/ESW-47 Paypal Integertion/";
}
return 26080; // bundleurl + 'JJ_HTML_MW_Form.html' // '13147'
},
gethtml: function(fileid, invoice) {
var scripturl = url.resolveScript({
scriptId: 'customscript_esw_47_paypal_integertion',
deploymentId: 'customdeployesw_47_paypal_integertion_ui',
returnExternalUrl: true
});
var invoicedata = main.getinvoicedata(invoice);
log.debug("invoicedata", invoicedata);
var itemtable = main.createitemtable(invoicedata.itemdetails, invoicedata.shippingcost);
log.debug("itemtable", itemtable)
try {
var fieldLookUp = record.load({
type: 'subsidiary',
id: invoicedata.subsidiary,
})
log.debug("fieldLookUp", fieldLookUp.getValue("logo"));
var fileurl = fieldLookUp.getValue("logo");
var fileurl = file.load({
id: fileurl
}).url
log.debug("fileurl", fileurl);
} catch (e) {
}
var fileObj = file.load({
id: fileid
});
if (fileObj.size < 10485760) {
var html = fileObj.getContents();
}
var ship = invoicedata.billaddress;
ship.replace(/\n/g, '<br>')
log.debug("ship", ship);
var newhtml = html.replace("<pricetag>", '<pricetag>');
var newhtml1 = newhtml.replace("<scripturl>", scripturl);
var newhtml2 = newhtml1.replace("<replacewithitemdetails>", itemtable);
var newhtml3 = newhtml2.replace("<pricetag>", invoicedata.totalamount);
var newhtml4 = newhtml3.replace("<customeraddressadd>", " ");
var newhtml5 = newhtml4.replace("<invoicecreateddate>", invoicedata.createddate);
var newhtml6 = newhtml5.replace(/<invoicetranid>/g, invoicedata.tranid);
var newhtml7 = newhtml6.replace(/<logourlreplace>/g, fileurl);
var newhtml8 = newhtml7.replace("*invoicetotals*", invoicedata.totalamount);
return newhtml8;
},
getinvoicedata: function(invocie) {
var resultrec = record.load({
type: record.Type.INVOICE,
id: parseInt(invocie),
isDynamic: true,
});
var recorddetails = {};
recorddetails.totalamount = resultrec.getValue({
fieldId: 'total'
});
recorddetails.subsidiary = resultrec.getValue({
fieldId: 'subsidiary'
});
recorddetails.shippingcost = resultrec.getValue({
fieldId: 'shippingcost'
});
recorddetails.createddate = resultrec.getValue({
fieldId: 'createddate'
});
recorddetails.billaddress = resultrec.getValue({
fieldId: 'billaddress'
});
recorddetails.tranid = resultrec.getValue({
fieldId: 'tranid'
});
var caf = resultrec.getText({
fieldId: 'billaddress'
});
log.debug("caf", caf);
var numLines = resultrec.getLineCount({
sublistId: 'item'
});
if (numLines > 0) {
var recdataarray = [];
for (var i = 0; i < numLines; i++) {
var recdata = {};
recdata.rate = resultrec.getSublistValue({
sublistId: 'item',
fieldId: 'amount',
line: i
});
recdata.item_display = resultrec.getSublistValue({
sublistId: 'item',
fieldId: 'item_display',
line: i
});
recdataarray.push(recdata);
}
recorddetails.itemdetails = recdataarray;
return recorddetails;
}
},
createitemtable: function(itemdetails, shippingcost) {
var html = '';
for (var i = 0; i < itemdetails.length; i++) {
html += '<tr class="item"><td>';
html += itemdetails[i].item_display + "</td><td>";
html += itemdetails[i].rate + "</td></tr>";
}
log.debug(shippingcost);
if (shippingcost != undefined)
html += '<tr class="item"><td> Shipping Cost</td><td>' + shippingcost + '</td></tr>';
return html;
},
genaratetoken: function() {
var Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function(e) {
var t = "";
var n, r, i, s, o, u, a;
var f = 0;
e = Base64._utf8_encode(e);
while (f < e.length) {
n = e.charCodeAt(f++);
r = e.charCodeAt(f++);
i = e.charCodeAt(f++);
s = n >> 2;
o = (n & 3) << 4 | r >> 4;
u = (r & 15) << 2 | i >> 6;
a = i & 63;
if (isNaN(r)) {
u = a = 64
} else if (isNaN(i)) {
a = 64
}
t = t + this._keyStr.charAt(s) +
this._keyStr.charAt(o) +
this._keyStr.charAt(u) +
this._keyStr.charAt(a)
}
return t
},
decode: function(e) {
var t = "";
var n, r, i;
var s, o, u, a;
var f = 0;
e = e.replace(/[^A-Za-z0-9+/=]/g, "");
while (f < e.length) {
s = this._keyStr.indexOf(e.charAt(f++));
o = this._keyStr.indexOf(e.charAt(f++));
u = this._keyStr.indexOf(e.charAt(f++));
a = this._keyStr.indexOf(e.charAt(f++));
n = s << 2 | o >> 4;
r = (o & 15) << 4 | u >> 2;
i = (u & 3) << 6 | a;
t = t + String.fromCharCode(n);
if (u != 64) {
t = t + String.fromCharCode(r)
}
if (a != 64) {
t = t + String.fromCharCode(i)
}
}
t = Base64._utf8_decode(t);
return t
},
_utf8_encode: function(e) {
e = e.replace(/rn/g, "n");
var t = "";
for (var n = 0; n < e.length; n++) {
var r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r)
} else if (r > 127 && r < 2048) {
t += String.fromCharCode(r >> 6 | 192);
t += String.fromCharCode(r & 63 | 128)
} else {
t += String.fromCharCode(r >> 12 | 224);
t += String.fromCharCode(r >> 6 & 63 | 128);
t += String.fromCharCode(r & 63 | 128)
}
}
return t
},
_utf8_decode: function(e) {
var t = "";
var n = 0;
var r = c1 = c2 = 0;
while (n < e.length) {
r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r);
n++
} else if (r > 191 && r < 224) {
c2 = e.charCodeAt(n + 1);
t += String.fromCharCode((r & 31) << 6 | c2 &
63);
n += 2
} else {
c2 = e.charCodeAt(n + 1);
c3 = e.charCodeAt(n + 2);
t += String.fromCharCode((r & 15) << 12 |
(c2 & 63) << 6 | c3 & 63);
n += 3
}
}
return t
}
}
var encodedString = Base64
.encode('AcgDXlqlH0a7GdavgfLy6IdDvVBe--8WBOrQnY7Ajw0UKgKmzge3r5YVfmRwxoE3DjKmC5wvh1QzV_v5:EAvZVQeKPrI2TPQo4KvcYwaNqzEihrF6HdYhE55ixEGyKsQxSWeqWTs_FYBTPFlhx3P3xLYscPoC1AQx');
var str = 'Basic ' + encodedString;
var header = {
'Authorization': str,
'Content-Type': 'application/x-www-form-urlencoded',
'Accept-Language': 'en_US',
'Accept': 'application/json'
};
var myPostDataObj = {
grant_type: 'client_credentials'
};
var response = https.post({
url: 'https://api.sandbox.paypal.com/v1/oauth2/token',
body: myPostDataObj,
headers: header
});
log.debug("genaratetoken response ", JSON.parse(response.body));
return JSON.parse(response.body).access_token;
}
}
for (var key in main) {
if (typeof main[key] === 'function') {
main[key] = trycatch(main[key], key);
}
}
function trycatch(myfunction, key) {
return function() {
try {
return myfunction.apply(this, arguments);
} catch (e) {
log.debug("e in " + key, e);
}
}
};
return main;
});
HTML Script
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script src="https://unpkg.com/sweetalert2@7.19.1/dist/sweetalert2.all.js"></script>
<script>
var invoice = '<invoiceinternalid>'
// Render the PayPal button
paypal.Button.render({
// Set your environment
env: 'sandbox', // sandbox | production
// Specify the style of the button
style: {
label: 'pay',
size: 'responsive', // small | medium | large | responsive
shape: 'rect', // pill | rect
color: 'blue' // gold | blue | silver | black
},
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: 'AaSHM9-7uO7msAu2rdGr_OYI0SIaFkdv4Vz44FzjjufYr1mafhmChkJIDHbfZ2mOI-yeJQsYrdOxlI1f',
production: '<insert production client id>'
},
// Wait for the PayPal button to be clicked
payment: function(data, actions) {
return actions.payment.create({
payment: {
transactions: [{
amount: { total: '<pricetag>', currency: 'USD' }
}]
}
});
},
// Wait for the payment to be authorized by the customer
onAuthorize: function(data, actions) {
console.log(data);
console.log(actions);
return actions.payment.execute().then(function() {
$.post("<scripturl>", {
datas: JSON.stringify(data),
invoice: '<invoicetranid>',
invoiceinternal: getParameterByName('invoice')
},
function(data, status) {
swal(
data + ' transaction',
' ',
'success'
)
});
});
}
}, '#paypal-button-container');
// for getting parameter by name .................
function getParameterByName(name, url) {
if (!url)
url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex
.exec(url);
if (!results)
return null;
if (!results[2])
return ' ';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
</script>