Amazon Simple Pay sends you outbound notifications in the form of GET and POST on your ReturnURL and IPN endpoint respectively. When you handle these notifications, we recommend you to validate the Signature to ensure that the notification actually originated from us. Signature V2 provides two ways to validate this signature.
This package contains the following files to help you validate IPN and Return URL notifications using signature version 2 programmatically on your end. If you would like to use Verify Signature Action, the samples are packaged under "IPNAndReturnURLValidation/src".
// @TODO: set request. Action can be passed as Amazon_FPS_Model_VerifySignatureRequest
// object or array of parameters
// invokeVerifySignature($service, $request);
$request= new Amazon_FPS_Model_VerifySignatureRequest();
$request->setUrlEndPoint("YourReturnUrl");
$request->setHttpParameters("QueryStringFromTheReturnUrl");
Return URL : http://yourwebsite.com/return.jsp
Parameters sent by ASP in ReturnUrl (using HTTP GET):
paymentReason = Test Widget
transactionDate = 1254987247
buyerName = test sender
recipientEmail = test-recipient@amazon.com
referenceId = test-reference123
paymentMethod = Credit Card
operation = pay
signatureMethod = RSA-SHA1
signature = VirmnCtqA/A+s+H+SE7Oj8Ku7Lfay6OKkJgP/Q0hyQeaR6evI8Usokg698utW6xzJsiUudXm0KpmqiWM33o1aby3AOxZ
qWUC//aMZPO9vdw1NWR5fOJ++8AR9BAfcUtTHWc2QOHa1UyJalqeMsHuQj2IqQCMmOAUHPFkHhwAZMS9Ifkkxjqczg4S0vK9FoO39rFY
kReYdL9SvuFyj6byAnqd3D7i/lgw+6jXjAlM9MqYiisMLyCGk0IQsrux5VbiQgI9LiGqUThGh7o2XkEFWvmPlKFmdQVnLxN9RNOK4pwr
ktbjgrBfVKZu1BBBXjfwwy9xzin0Kw5uNlCD2ReoZA==
buyerEmail = test-sender@amazon.com
transactionAmount = USD 1.1
status = PS
recipientName = Test Business
transactionId = 14GPH3CZ83RPQ1ZH6J2G85NL1IO3KO8641R
signatureVersion = 2
certificateUrl = https://fps.sandbox.amazonaws.com/certs/090909/PKICert.pem
The above code snippet will look like:
$request= new Amazon_FPS_Model_VerifySignatureRequest();
$request->setUrlEndPoint("http://yourwebsite.com/return.jsp");
$request->setHttpParameters("paymentReason=Test+Widget&transactionAmount=USD+1.1&signatureMethod=RSA-SHA1&
transactionId=14GPH3CZ83RPQ1ZH6J2G85NL1IO3KO8641R&status=PS&buyerEmail=test-sender%40amazon.com&
referenceId=test-reference123&recipientEmail=test-recipient%40amazon.com&transactionDate=1254987247&
buyerName=test+sender&operation=pay&recipientName=Test+Business&signatureVersion=2&signature=VirmnCtqA%2FA
%2Bs%2BH%2BSE7Oj8Ku7Lfay6OKkJgP%2FQ0hyQeaR6evI8Usokg698utW6xzJsiUudXm0KpmqiWM33o1aby3AOxZqWUC%2F%2FaMZPO9v
dw1NWR5fOJ%2B%2B8AR9BAfcUtTHWc2QOHa1UyJalqeMsHuQj2IqQCMmOAUHPFkHhwAZMS9Ifkkxjqczg4S0vK9FoO39rFYkReYdL9SvuF
yj6byAnqd3D7i%2Flgw%2B6jXjAlM9MqYiisMLyCGk0IQsrux5VbiQgI9LiGqUThGh7o2XkEFWvmPlKFmdQVnLxN9RNOK4pwrktbjgrBfV
KZu1BBBXjfwwy9xzin0Kw5uNlCD2ReoZA%3D%3D&certificateUrl=https%3A%2F%2Ffps.sandbox.amazonaws.com%2Fcerts%2F0
90909%2FPKICert.pem&paymentMethod=Credit+Card");
Note: If your return url contains query string like http://yourwebsite.com/return.jsp?a=b&c=d, concat
&URLEncode(a)=URLEncode(b)&URLEncode(c)=URLEncode(d) to the HttpParameters input.
VerifySignatureResponse VerifySignatureResult VerificationStatus Success ResponseMetadata RequestId 197e2085-1ed7-47a2-93d8-d76b452acc74:0
// @TODO: set request. Action can be passed as Amazon_FPS_Model_VerifySignatureRequest
// object or array of parameters
// invokeVerifySignature($service, $request);
$request= new Amazon_FPS_Model_VerifySignatureRequest();
$request->setUrlEndPoint("YourIPNUrl");
$request->setHttpParameters("QueryStringFromTheIPNUrl");
IPN URL : http://yourwebsite.com/ipn.jsp
Parameters sent by ASP in IPN (using HTTP POST):
transactionId: 14GPH3CZ83RPQ1ZH6J2G85NL1IO3KO8641R
transactionDate: 1254987247
signatureVersion: 2
signatureMethod: RSA-SHA1
status: PS
buyerEmail: test-sender@amazon.com
referenceId: test-reference123
operation: pay
transactionAmount: USD 1.100000
recipientEmail: test-recipient@amazon.com
buyerName: test sender
signature: g2tEn6VVu8VKsxnkWeCPn8M9HABkzkVGbYTozSSKg9Y7B5Xsvq5GSoXkDlaz+izQM56wzvgFCou7
9un06KI6CeE4lf0SSsonoPInqvTrKoS/XPZqBChtdfciCqSyWBpPZ2YaEbSYEZdk1YZW0W7oeezg
QqgzBL/CLN9U128GyFllt3/Yxr6p+XBltBUjh0kGmdAFVuFgwYq7h7cyMwAyseIRU7vDW5qsTreA
PBmae9h3v4oZly5CyNDP+4HhExyzakf2r+UBEqj9EwZtek3k9qj956dlG8Dd3QeEF9AqjLp0D+7M
yZr0rupNcWNbO1wGX8aEda/FvoWMRxXB3sU9dw==
recipientName: Test Business
paymentMethod: CC
certificateUrl: https://fps.sandbox.amazonaws.com/certs/090909/PKICert.pem
paymentReason: Test Widget
The above code snippet will look like:
$request= new Amazon_FPS_Model_VerifySignatureRequest();
$request->setUrlEndPoint("http://yourwebsite.com/ipn.jsp");
$request->setHttpParameters("paymentReason=Test+Widget&signatureMethod=RSA-SHA1&
transactionAmount=USD+1.100000&transactionId=14GPH3CZ83RPQ1ZH6J2G85NL1IO3KO8641R&status=PS&
buyerEmail=test-sender%40amazon.com&referenceId=test-reference123&recipientEmail=test-recipient%40amazon.com
&transactionDate=1254987247&buyerName=test+sender&operation=pay&recipientName=Test+Business&signatureVersion=2
&signature=g2tEn6VVu8VKsxnkWeCPn8M9HABkzkVGbYTozSSKg9Y7B5Xsvq5GSoXkDlaz%2BizQM56wzvgFCou79un06KI6CeE4lf0SSson
oPInqvTrKoS%2FXPZqBChtdfciCqSyWBpPZ2YaEbSYEZdk1YZW0W7oeezgQqgzBL%2FCLN9U128GyFllt3%2FYxr6p%2BXBltBUjh0kGmdAFV
uFgwYq7h7cyMwAyseIRU7vDW5qsTreAPBmae9h3v4oZly5CyNDP%2B4HhExyzakf2r%2BUBEqj9EwZtek3k9qj956dlG8Dd3QeEF9AqjLp0D
%2B7MyZr0rupNcWNbO1wGX8aEda%2FFvoWMRxXB3sU9dw%3D%3D&certificateUrl=https%3A%2F%2Ffps.sandbox.amazonaws.com%2F
certs%2F090909%2FPKICert.pem&paymentMethod=CC");
Note: If your ipn url contains query string like http://yourwebsite.com/ipn.jsp?a=b&c=d, concat
&URLEncode(a)=URLEncode(b)&URLEncode(c)=URLEncode(d) to the HttpParameters input.
VerifySignatureResponse VerifySignatureResult VerificationStatus Success ResponseMetadata RequestId 197e2085-1ed7-47a2-93d8-d76b452acc74:0Summary of the steps to use VerifySignature action for Return URL and IPN:
1 |
Capture the notification on on your IPN endpoint |
2 |
Construct VerifySignature request by specifying either your Return URL or IPN endpoint as “UrlEndpoint” and the concatenated string of HTTP parameters as “HttpParameters” [‘=’ used as delimiter between URL encoded name, URL encoded value and ‘&’ used as delimiter between each name, value pair.] |
3 |
Invoke VerifySignature request against Sandbox or Production endpoint as applicable |
4 |
Capture the XML response and decide whether to process the IPN notification or discard it based on the value of “VerificationStatus” boolean. |
//Parameters present in return url.
$params["transactionId"] = "14GPH3CZ83RPQ1ZH6J2G85NL1IO3KO8641R";
$params["transactionDate"] = "1254987247";
$params["status"] = "PS";
$params["signatureMethod"] = "RSA-SHA1";
$params["signatureVersion"] = "2";
$params["buyerEmail"] = "test-sender@amazon.com";
$params["recipientEmail"] = "test-recipient@amazon.com";
$params["operation"] = "pay";
$params["transactionAmount"] = "USD 1.1";
$params["referenceId"] = "test-reference123";
$params["buyerName"] = "test sender";
$params["recipientName"] = "Test Business";
$params["paymentMethod"] = "Credit Card";
$params["paymentReason"] = "Test Widget";
$params["certificateUrl"] = "https://fps.sandbox.amazonaws.com/certs/090909/PKICert.pem";
$params["signature"] = "VirmnCtqA/A+s+H+SE7Oj8Ku7Lfay6OKkJgP/Q0hyQeaR6evI8Usokg698utW6xzJsiUudXm0K"
. "pmqiWM33o1aby3AOxZqWUC//aMZPO9vdw1NWR5fOJ++8AR9BAfcUtTHWc2QOHa1UyJalqeMsHuQj2IqQCMmOAUHPFkHhwAZ"
. "MS9Ifkkxjqczg4S0vK9FoO39rFYkReYdL9SvuFyj6byAnqd3D7i/lgw+6jXjAlM9MqYiisMLyCGk0IQsrux5VbiQgI9LiGqU"
. "ThGh7o2XkEFWvmPlKFmdQVnLxN9RNOK4pwrktbjgrBfVKZu1BBBXjfwwy9xzin0Kw5uNlCD2ReoZA==";
$urlEndPoint = "http://yourwebsite.com/return.jsp"; //Your return url end point.
print "Verifying return url signed using signature v2 ....\n";
//return url is sent as a http GET request and hence we specify GET as the http method.
//Signature verification does not require your secret key
print "Is signature correct: " . $utils->validateRequest($params, $urlEndPoint, "GET") . "\n";
//Parameters present in ipn.
$params["transactionId"] = "14GPH3CZ83RPQ1ZH6J2G85NL1IO3KO8641R";
$params["transactionDate"] = "1254987247";
$params["status"] = "PS";
$params["signatureMethod"] = "RSA-SHA1";
$params["signatureVersion"] = "2";
$params["buyerEmail"] = "test-sender@amazon.com";
$params["recipientEmail"] = "test-recipient@amazon.com";
$params["operation"] = "pay";
$params["transactionAmount"] = "USD 1.100000";
$params["referenceId"] = "test-reference123";
$params["buyerName"] = "test sender";
$params["recipientName"] = "Test Business";
$params["paymentMethod"] = "CC";
$params["paymentReason"] = "Test Widget";
$params["certificateUrl"] = "https://fps.sandbox.amazonaws.com/certs/090909/PKICert.pem";
$params["signature"] ="g2tEn6VVu8VKsxnkWeCPn8M9HABkzkVGbYTozSSKg9Y7B5Xsvq5GSoXkDlaz+izQM56wzvgFCou"
. "79un06KI6CeE4lf0SSsonoPInqvTrKoS/XPZqBChtdfciCqSyWBpPZ2YaEbSYEZdk1YZW0W7oeezgQqgzBL/CLN9U128GyF"
. "llt3/Yxr6p+XBltBUjh0kGmdAFVuFgwYq7h7cyMwAyseIRU7vDW5qsTreAPBmae9h3v4oZly5CyNDP+4HhExyzakf2r+UBE"
. "qj9EwZtek3k9qj956dlG8Dd3QeEF9AqjLp0D+7MyZr0rupNcWNbO1wGX8aEda/FvoWMRxXB3sU9dw==";
$urlEndPoint = "http://yourwebsite.com/ipn.jsp"; //Your url end point receiving the ipn.
print "Verifying IPN signed using signature v2 ....\n";
//IPN is sent as a http POST request and hence we specify POST as the http method.
//Signature verification does not require your secret key
print "Is signature correct: " . $utils->validateRequest($params, $urlEndPoint, "POST") . "\n";
Summary of the steps to use PKI algorithm for Return URL and IPN:
1 |
Decode the signature in the notification. |
2 |
Decode and read the signatureVersion and signatureMethod parameters from the notification. In the current implementation, signatureVersion value should be 2 and signatureMethod value should be RSA-SHA1 (format is Algorithm-Digest). |
3 |
Decode and read the certificateUrl parameter from the notification. |
4 |
Check if the certificate corresponding to the URL was already downloaded and cached. |
5 |
If the certificate was not cached, download the same and cache it. |
6 |
Compute the StringToSign using the V2 algorithm (same as inbound requests) – StringToSign should include all the parameters sent in the notification excluding signature. |
7 |
Validate the signature using the StringToSign and the Certificate downloaded. |
8 |
If the signatures match, the notification is processed. Otherwise, the notification is discarded. |