Code Sample
Collecting payments and updating existing account details
Client Code
function loadPaysimpleJs(auth, customerAuth) {
// Initialize the PaySimpleJS SDK with the checkout token and styles
var paysimplejs = window.paysimpleJs({
debug: true,
container: document.querySelector('#psjs'),
auth: auth,
customerAuth: customerAuth,
styles: {
body: {
backgroundColor: '#f9f9f9'
}
}
});
var psjsFormValid = false;
// Configure a callback to complete the checkout after the
// PaySimpleJS SDK retrieves the account
paysimplejs.on('accountRetrieved', onAccountRetrieved);
paysimplejs.on('formValidityChanged', function(body) {
psjsFormValid = body.valid;
});
// Load the credit card or ach key enter form
if (window.location.href.indexOf('ach=1') > 0) {
paysimplejs.send.setMode('ach-key-enter');
}
else {
paysimplejs.send.setMode('cc-key-enter');
}
// Add an event listener to your submit button
document.querySelector('#sample-form')
.addEventListener('submit', onSubmit);
// Called when the PaySimpleJS SDK retrieves the account info
function onAccountRetrieved(accountInfo) {
/* Example accountInfo:
* {
* "account": {
* "id": 7313702
* },
* "customer": {
* "id": 8041997
* },
* "paymentToken": "e1f1bb19-9fe4-4c96-a35e-cd921298d8e6"
* }
*/
// Send the accountInfo to your server to collect a payment
// for an existing customer
var xhr = new XMLHttpRequest();
xhr.open('POST', 'PaySimple/Payment');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function(e) {
if (xhr.status < 300) {
var data = JSON.parse(this.response);
document.getElementById('message')
.innerHTML = 'Successfully created Payment:\nTrace #: ' + data.TraceNumber;
//alert('Successfully created Payment:\nTrace #: ' + data.TraceNumber);
} else {
document.getElementById('message')
.innerHTML = 'Failed to create Payment: (' + xhr.status + ')' + xhr.responseText;
// alert('Failed to create Payment: (' + xhr.status + ') '
// + xhr.responseText);
}
}
accountInfo.amount = document.querySelector('#amount').value;
xhr.send(JSON.stringify(accountInfo));
}
// Submit button event listener -- triggered when the user clicks
// the submit button.
// Sumbits the merchant form data to the PaySimpleJS SDK
function onSubmit(event) {
// Prevent the default submit behavior of the form
event.preventDefault();
document.getElementById('message').innerHTML = '';
// Request the PaySimpleJS SDK to add a new cc or ach account for the
// customer which the server generated the customer token was granted
getCustomerToken(function(customerToken) {
return paysimplejs.send.matchOrCreateAccount(customerToken);
});
}
}
function getToken(tokenType, callback) {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'PaySimple/' + tokenType);
xhr.onload = function(e) {
if (xhr.status < 300){
var data = JSON.parse(this.response);
callback.call(null, {
token: data.JwtToken
});
return;
}
alert('Failed to get Auth Token: (' + xhr.status + ') '
+ xhr.responseText);
}
xhr.send();
}
function getAuth(callback) {
getToken('CheckoutToken', callback);
}
function getCustomerToken(callback) {
getToken('CustomerToken', callback);
}
getAuth(loadPaysimpleJs);
Server Code
using System;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Mvc;
using PaySimpleSdk.Accounts;
using PaySimpleSdk.Customers;
using PaySimpleSdk.Models;
using PaySimpleSdk.Payments;
namespace PaySimple.NetSDKSample.Web.Controllers
{
public class PaySimpleController : Controller
{
private static readonly IPaySimpleSettings PSSettings = new PaySimpleSettings(ConfigurationManager.AppSettings["PS.ApiKey"], ConfigurationManager.AppSettings["PS.UserId"],
ConfigurationManager.AppSettings["PS.BaseUrl"]);
[HttpPost]
public async Task<ActionResult> CheckoutToken()
{
var paymentService = new PaymentService(PSSettings);
var token = await paymentService.GetCheckoutTokenAsync();
return Json(token);
}
[HttpPost]
public async Task<ActionResult> PaymentToken(PaymentTokenRequest paymentTokenRequest)
{
var paymentService = new PaymentService(PSSettings);
var token = await paymentService.GetPaymentTokenAsync(paymentTokenRequest);
return Json(token);
}
[HttpPost]
public async Task<ActionResult> CustomerToken()
{
var customerService = new CustomerService(PSSettings);
// do not allow the customer id to be passed in from the UI here or any
// customer would have access to other customers data!
// in real life this would be usually mapped to a logged in user's account
// on your system.
var customerId = (await customerService.GetCustomersAsync()).Items.FirstOrDefault()?.Id;
if (!customerId.HasValue)
throw new ApplicationException("No customer exists to use");
var token = await customerService.GetCustomerTokenAsync(customerId.Value);
return Json(token);
}
[HttpPost]
public async Task<ActionResult> Payment(decimal amount, Account account, Customer customer, string paymentToken)
{
var payment = new Payment
{
Amount = amount,
AccountId = account.Id,
PaymentToken = paymentToken
};
var paymentService = new PaymentService(PSSettings);
payment = await paymentService.CreatePaymentAsync(payment);
return Json(payment);
}
}
}
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const crypto = require('crypto');
// Replace username and apikey with your PaySimple 4.0 API credentials
const settings = {
port: 8080,
apiv4url: https: //api.paysimple.com/v4, // set to https://sandbox-api.paysimple.com/v4 for testing in the sandbox environment
username: 'APIUser9999999',
apikey: 'NTqVg...V8W0'
};
let app = express();
app.use(express.static('public'));
app.use(bodyParser.json());
// The authorization header for PaySimple 4.0
function getAuthHeader() {
let time = (new Date()).toISOString();
let hash = crypto.createHmac('SHA256', settings.apikey)
.update(time)
.digest('base64');
return 'PSSERVER ' + "accessid=" + settings.username +
"; timestamp=" + time + "; signature=" + hash;
}
// Simple endpoint to communicate with PaySimple 4.0 API to retrieve a JWT
// that can be passed to the PaySimpleJS.
// Example response body:
// {
// "JwtToken": "eyJ0eXAiOiJKV1...lNbw",
// "Expiration":"2017-02-28T22:03:36Z"
// }
app.get('/token', function(req, res) {
let options = {
method: "POST",
uri: settings.apiv4url + '/checkouttoken',
headers: {
Authorization: getAuthHeader()
},
body: {},
json: true,
};
request(options, function(error, response, body) {
if (!error && response && response.statusCode < 300) {
res.json(body.Response);
return;
}
res.status((response && response.statusCode) || 500).send(error);
});
});
// Mocked up endpoint to initiate a payment via the PaySimple 4.0 API with
// the payment token returned by the PaySimpleJS
app.post('/payment', function(req, res) {
var accountInfo = req.body;
let options = {
method: "POST",
uri: settings.apiv4url + '/payment',
headers: {
Authorization: getAuthHeader()
},
body: {
AccountId: accountInfo.account.id,
PaymentToken: accountInfo.paymentToken,
// Payment Specific information...
Amount: 3.50,
PurchaseOrderNumber: '123456',
OrderId: 'O-4242',
Description: 'Really good description of order',
PaymentSubType: 'MOTO'
},
json: true,
};
request(options, function(error, response, body) {
// The return code for /payment will be a 201 (CREATED)
if (!error && response && response.statusCode < 300) {
res.json(body.Response);
return;
}
res.status((response && response.statusCode) || 500).send(error);
});
});
// Endpoint to get a JWT token for a customer that has been authenticated
// by the merchant. The PaySimple customer id should NOT be passed into this service
// to prevent unauthorized access.
app.get('/customertoken, function(req, res) {
let customerid = 1234; // do a lookup in your system to fetch the PaySimple customer id for the authenticated customer
let options = {
method: "GET",
uri: settings.apiv4url + '/customer/' + customerId + "/token",
headers: {
Authorization: getAuthHeader()
},
json: true,
};
request(options, function(error, response, body) {
if (!error && response && response.statusCode < 300) {
res.json(body.Response);
return;
}
res.status((response && response.statusCode) || 500).send(error);
});
});
app.listen(settings.port, function() {
console.log('PaySimpleJS backend listening on port ' + settings.port);
});
Updated over 2 years ago