Pivot
Overview
EdgePay Pivot is a JavaScript Library and Function that you can add to your Payment page and bypass sending sensitive card data to your server, thus eliminating the risks associated with storing, processing, or transmitting credit card data and allows you to operate in a PCI Compliance way.
You would use this Library and Function if do not want to store, process, or transmit card data on your system. If your design already includes server-side card processing, this library and function may not be for you.
Implementation
For Production processing you will use the Merchant Key, Merchant ID, and Terminal ID we setup for you. For testing purposes please feel free to use the information provided below in the code snippets.
EdgePay Pivot is a 2-step process:
Step 1: At the point of “Checkout” your Server-Side code will execute the following code to retrieve a 1-time Pivot Authentication Key from our Server. This 1-time use key allows you to use the EdgePay Pivot to get a 1-time Token to replace the Card data.
The 1-time Pivot Authentication Key is valid for only 15 minutes, then expires. The key is also not valid after it has been submitted and used.
Step 2: After you get your One-Time Token you will then be able to return to your Server and use the API to process a Payment request.
Here is the code you would use to request the 1-Time Pivot Authentication Key from your server.
Java
OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{ \r\n \"merchantID\":\"6320340123456901\",\r\n \"terminalID\":\"88800000282601\"\r\n}\r\n "); Request request = new Request.Builder().url("https://api.edgepay- uat.com/generatePivotAuthKey").post(body).addHeader("Content-Type", "application/json").addHeader("merchantKey", "C8E05D70D3C8D3D675EAA2FE86674FEA3BCE1AFBECA4322C ").addHeader("externalReferenceID", "1234561528498479").addHeader("transactionDate", "2018-06- 08T00:01:00").addHeader("Cache-Control", "no-cache").build(); Response response = client.newCall(request).execute();
Python
import http.client conn = http.client.HTTPConnection("api.edgepay-uat,com") payload = "{ \r\n \"merchantID\":\"6320340123456901\",\r\n \"terminalID\":\"88800000282601\"\r\n}\r\n " headers = { 'Content-Type': "application/json", 'merchantKey': "C8E05D70D3C8D3D675EAA2FE86674FEA3BCE1AFBECA4322C ", 'externalReferenceID': "1234561528498328", 'transactionDate': "2018-06-08T00:01:00", 'Cache-Control': "no-cache" } conn.request("POST", "generatePivotAuthKey", payload, headers) res = conn.getresponse() data = res.read() 19. print(data.decode("utf-8"))
C#
var client = new RestClient("https://api.edgepay-uat.com/generatePivotAuthKey"); var request = new RestRequest(Method.POST); request.AddHeader("Cache-Control", "no-cache"); request.AddHeader("transactionDate", "2018-06-08T00:01:00"); request.AddHeader("externalReferenceID", "1234561528498677"); request.AddHeader("merchantKey", "C8E05D70D3C8D3D675EAA2FE86674FEA3BCE1AFBECA4322C"); request.AddHeader("Content-Type", "application/json"); request.AddParameter("undefined", "{ \r\n \"merchantID\":\"6320340123456901\",\r\n \"terminalID\":\"88800000282601\"\r\n}\r\n ", ParameterType.RequestBody); IRestResponse response = client.Execute(request);
Pivot Key Responses
This request will return the following response to your Server as an Approved Transaction, providing your Server a 1-Time Pivot Key.
Success:
{ "result": "A", "responseCode": "EP0020", "responseMessage": "Pivot Key Generation Successful", "timestamp": "2018-06-08 22:35:42.486", "pivotAuthKey": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJtZXJjaGFudEtleVwiOlwiTnlCNWJPT01jT1EwZkIvZnVnMXpQZE1WQ05HVU5iZmdyMUt2c2FlNmE5NFprY0hqdEE3MkRVZWptTGxKcnFVejBuWithVUZoU3ZSZE42amdmdkNRYXN3aE9jMm80bGd1YjV5NmQ2eEJQdDg9XCIsXCJtZXJjaGFudElEXCI6XCI2MzIwMzQwMTIzNDU2NzIyXCIsXCJ0ZXJtaW5hbElEXCI6XCI4ODgwMDAwMDI4MjYwMVwiLFwiZXhwaXJlc0luU2Vjb25kc1wiOjkwMCxcImdlbmVyYXRpb25UaW1lSW5NaWxsaXNcIjoxNTI4NDk3MzQyNDg0fSIsImlhdCI6MTUyODQ5NzM0Mn0.1Ytwan7EvC4EqvsQ-dsS4iiXAQd_zTWqAFigDqnJvR0" }
There can also be a negative response in the request for a 1-Time Pivot Key. This can come in the form of ‘Decline, Retry, or Call for Help’ within the result field.
Error:
{ "result": "R", "responseCode": "EP0900", "responseMessage": "Message format not supported" } { "result": "D", "responseCode": "EP0102", "responseMessage": "The value '63203401234567221' of element 'merchantID' is not valid." }
Dealing with Pivot Key Responses
Here is a table of all responses and appropriate action to take:
Result | Response Code | Response Message | Recommended Next Action |
---|---|---|---|
A | EP0020 | Pivot Key Generation Successful | Use the Pivot Key to generate Payment Page |
C | EP0900 | Message format not supported | Call GET for support |
C | EP0102 | The value 'xxx' of element 'merchantID' is not valid | The Merchant ID in the request packet is not valid. Verify your input |
C | EP0102 | The value 'xxx' of element 'terminalID' is not valid | The Terminal ID in the request packect is not valid. Verify your input |
C | EP0012 | Authentication failed, please use valid credentials | The Merchant Key is not valid. Update Merchant key. |
D | EP0101 | The value of element 'externalReferenceID' is missing | The externalReferenceID must be included with every request, and be unique |
D | EP0101 | The value of element 'merchantID' is missing | The merchantID must be included with every request, and be unique |
D | EP0101 | The value of element 'terminalID' is missing | The terminalID must be included with every request, and be unique |
R | EP0999 | System Error | Internal Server error, please retry request |
Full Response Format
Here are the details of the Pivot Key response message:
Field | Attribute | Description |
---|---|---|
result | A/1 | A = Approved D = Decline R = Retry C = Call for Help |
responseCode | AN/6 | The 6-digit code and the table below may be used for determining next step in your code |
result | A/1 | A = Approved D = Decline R = Retry C = Call for Help |
responseMessage | AN String | Text describing the condition |
timestamp | N/Calendar | YYYY-MM-DD-hh-mm-ss |
pivotAuthKey | 256 bits | JSON Web Key |
Once you have your 1-time Pivot Authentication Key, you are ready to request the payment. Include the following code as part of generating the HTML page for the Payment Page.
<script type = "text/javascript" src = "https://static.portal.edgepay-uat.com/public/js/edgepayPivot.min.js"></script> <script type = "text/javascript"> EdgePay.init({ pivotAuthKey: "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJtZXJjaGFudEtleVwiOlwiTGdSWERva21mbGc1Y3F4anVVUG5aRlpLVHpGZ1hFZGt0Vlo0YkNybnllVHdIeXJ0YW53UDhOQW5kbmFwNm9xU3o0SnNIaDVNTm5SNWFFWTBMUThCdHEzVmRibEcwL3YvK21JMWJlYm92WjA9XCIsXCJtZXJjaGFudElEXCI6XCI2MzIwMzQwMTIzNDU2NzIyXCIsXCJ0ZXJtaW5hbElEXCI6XCI4ODgwMDAwMDI4MjYwMVwiLFwiZXhwaXJlc0luU2Vjb25kc1wiOjkwMCxcImdlbmVyYXRpb25UaW1lSW5NaWxsaXNcIjoxNTI4NDk5NTU3NDQzfSIsImlhdCI6MTUyODQ5OTU1N30.hyP_IeBSjd9bLb-cXfAik-Yf9gcDnWjE6Fe29EPpG0c" (This is the key from the 1-time pivot key request) }); EdgePay.getToken({ formFieldIdSelector: { submitButton: "btnSubmit", cardNumber: "inputCreditCard", cardExpirationDate: "inputExpirationDate", cvv2: "inputCVV2" }, onSuccess: function(success) { /*success call back to applied business logic*/ /*tokenID can be found in success.body.tokenID */ document.getElementById("token").value= success.body.tokenID; document.getElementById("paymentForm").submit(); }, onError: function(error) { /*error call back to applied business logic*/ } }); </script>
If your page has a card expiration date in two different fields (month and year), you can replace the cardExpirationDate field with the cardExpirationMonth and cardExpirationYear fields in the getToken function:
EdgePay.getToken({ formFieldIdSelector: { submitButton: "btnSubmit", cardNumber: "inputCreditCard", cardExpirationMonth: "inputExpiryMonth", cardExpirationYear: "inputExpiryYear", cvv2: "inputCVV2" },
This function will download the EdgePay JavaScript library and add to the user’s browser.
Within the code you added are the variables that holds the 1-time Pivot Authentication Key. Please insert the key you retrieved from the previous request in the pivotAuthKey variable when you build the page.
Also, within the code is the definitions required to download the library to process the Card information and return the 1-Time token. The code controls the input variables and submit button as well as handling an Ajax Method that will get fired from executing the Submit button. This method will send the Card Information to EdgePay using the 1-Time Pivot Key for Authentication.
For your Payment form most of the variables are fixed but we recognize there are several approaches to Card Expiration Date. Thus, we have enabled the following formats within the EdgePay Pivot Library:
Card Expiration dates supported:
- MMYY
- MMYYYY
- MM/YY
- MM YY (2 Fields)
- MM YYYY (2 Fields)
Feel free to create the Card Expiration format that best fits your page and needs.
The JavaScript library will perform the following edits as part of entry on the form:
Error Type | Field Name | Error Text | Raw |
---|---|---|---|
VALIDATION_FAILED | cardNumber | This is required | {"errorType":"VALIDATION_FAILED","body":[{"fieldName":"cardNumber","errorText":"This is required"}]} |
VALIDATION_FAILED | cardNumber | Must be a number | {"errorType":"VALIDATION_FAILED","body":[{"fieldName":"cardNumber","errorText":"Must be a number"}]} |
VALIDATION_FAILED | cardExpirationField | Card Expiration Field is required | {"errorType":"VALIDATION_FAILED","body":[{"fieldName":"cardExpirationField","errorText":"Card Expiration Field is required"}]} |
VALIDATION_FAILED | cardExpirationDate | Card Expiration format not matched | {"errorType":"VALIDATION_FAILED","body":[{"fieldName":"cardExpirationDate","errorText":"Card Expiration format not matched"}]} |
VALIDATION_FAILED | cardExpirationMonth/cardExpirationYear | Card Expiration format not matched | {"errorType":"VALIDATION_FAILED","body":[{"fieldName":"cardExpirationMonth/cardExpirationYear","errorText":"Card Expiration format not matched"}]} |
VALIDATION_FAILED | cardExpirationField | Please input extra cardExpirationField field or combination of cardExpirationMonth and cardExpirationYear fields | {"errorType":"VALIDATION_FAILED","body":[{"fieldName":"cardExpirationField","errorText":"Please input cardExpirationField field or combination of cardExpirationMonth and cardExpirationYear fields"}]} |
VALIDATION_FAILED | cvv2 | Must be a number | {"errorType":"VALIDATION_FAILED","body":[{"fieldName":"cvv2","errorText":"Must be a number"}]} |
These edits will be corrected by the User before the code will allow the user to proceed. Upon the user selecting the Submit button the JavaScript library that is downloaded executes a request to EdgePay and returns a 1-Time token to replace the Card information, (Credit Card Number, Expiration Date, and CVV Value). This token is time sensitive as well and will expire in 15 minutes.
One Time Token Responses
You will use the "OnSuccess" Call back method to generate your POST back to your server with your order information and the 1-Time token which is now ready to make the payment from your server using the EdgePay Payment API and inputting the Token instead of the Credit Card information.
Here is the "OnSuccess" response message:
{body":{"result":"A","responseCode":"EP0081","responseMessage":"Successful","merchantID":"6320340123456722","tokenID":"5839914216406751","cardExpirationDate":"0220"},"status":200}"
If you receive an "OnError" result, use the workflow below to facilitate next steps for your development. These can be performed on form via JavaScript or back at your server.
Result | Response Code | Response Message | Raw | Recommended Next Action |
---|---|---|---|---|
R | EP0999 | System error | {"errorType":"SERVICE_INVOCATION_ERROR", "body":{"result":"R","responseCode":"EP0999", "responseMessage":"System error", "timestamp":"2018-06-12-14-43-55"},"status":500} | Request a new 1-Time Pivot Key and resend request |
D | EP0055 | Invalid Expiry Date | {"errorType":"SERVICE_INVOCATION_ERROR", "body":{"result":"D","responseCode":"EP0055", "responseMessage":"Invalid Expiry Date (MMYY)","merchantID":"6320340123456722", "cardExpirationDate":"1111"},"status":400} |
Display result to user and request corrected Date. Note; Requires a new Pivot Key |
D | EP0012 | Authentication failed, please use valid credentials | {"errorType":"SERVICE_INVOCATION_ERROR","body":{"result":"D","responseCode":"EP0012","responseMessage":"Authentication failed, please use valid credentials."},"status":400} | The 1-time Key was invalid. Request another 1-Time key and resubmit |
C | EP0900 | Message format not supported | {"errorType":"SERVICE_INVOCATION_ERROR","body":{"result":"C","responseCode":"EP0900","responseMessage":"Message format not supported"},"status":400} | This is an internal Key error. Call for help! |
D | EP0054 | Card number is invalid | {"errorType":"SERVICE_INVOCATION_ERROR","body":{"result":"D","responseCode":"EP0054","responseMessage":"Card number is invalid","merchantID":"6320340123456722","cardExpirationDate":"0220"},"status":400} | The customer input an invalid card. Get a new key and prompt to retry card input |
D | EP0102 | The value 'XXXX' of element 'cardExpirationDate' is not valid | {"errorType":"SERVICE_INVOCATION_ERROR","body":{"result":"D","responseCode":"EP0102","responseMessage":"The value '0200' of element 'cardExpirationDate' is not valid."},"status":400} | The customer input an invalid Expiration date. Get a new key and prompt to retry Card Expiration input |
Request the Payment
After you get your One-Time Token you can now return to your Server and use the API to process a Payment request. In the Payment Request, you can also request a Token and you will receive a Reusable token you can store on your server for future use.
Use the Payment Response Result to determine your next action. If the Payment Response is an “OnError” response and you wish to ask the Customer for another form of payment or re-enter your card information you must first request another 1-Time Authentication Key and load asynchronously to the current Payment page, then display the work flow instructions to the user.