Skip to content

Instantly share code, notes, and snippets.

@islandskater43
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save islandskater43/c5b3a98e37133840c44f to your computer and use it in GitHub Desktop.
Save islandskater43/c5b3a98e37133840c44f to your computer and use it in GitHub Desktop.
Simple PHP SDK for Amazon's Login and Pay Product
<?php
class LoginAndPayWithAmazon {
private $sandbox;
private $merchantId;
private $accessKey;
private $secretKey;
// find your endpoint here: http://docs.developer.amazonservices.com/en_US/dev_guide/DG_Endpoints.html
private $endpoint = 'https://mws.amazonservices.com';
private $url;
private $apiVersion = '2013-01-01';
private $sigAlgorithm = "HmacSHA256";
private $lastResponse;
private $paramList;
public function __construct( $merchantId , $accessKey , $secretKey , $sandbox ) {
$this->sandbox = $sandbox;
$this->merchantId = $merchantId;
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
$this->url = ($this->sandbox ? '/OffAmazonPayments_Sandbox' : '/OffAmazonPayments') . "/" . $this->apiVersion;
$this->paramList = array();
}
public function getOrderReferenceDetails ( $amazonOrderReferenceId ) {
$mwsResponse = $this->apiRequest ("GetOrderReferenceDetails" , "POST" , array("Action"=>"GetOrderReferenceDetails","AmazonOrderReferenceId"=>$amazonOrderReferenceId));
$this->lastResponse = $mwsResponse;
return $mwsResponse->getResponse();
}
public function setOrderReferenceDetails ( $amazonOrderReferenceId , $orderAmount ) {
$mwsResponse = $this->apiRequest("SetOrderReferenceDetails","POST",array("Action"=>"SetOrderReferenceDetails","AmazonOrderReferenceId"=>$amazonOrderReferenceId,"OrderReferenceAttributes.OrderTotal.Amount"=>$orderAmount,"OrderReferenceAttributes.OrderTotal.CurrencyCode"=>"USD"));
$this->lastResponse = $mwsResponse;
if($mwsResponse->getHttpCode() == "200") {
return true;
} else {
return false;
}
}
/* confirmOrderReference
* returns boolean
*/
public function confirmOrderReference( $amazonOrderReferenceId ) {
$mwsResponse = $this->apiRequest ("ConfirmOrderReference" , "POST" , array("Action"=>"ConfirmOrderReference","AmazonOrderReferenceId"=>$amazonOrderReferenceId));
$this->lastResponse = $mwsResponse;
if($mwsResponse->getHttpCode() == "200") {
return true;
} else {
return false;
}
}
/* authorize
* Docs - http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_Authorize.html
*/
public function authorize ( $amazonOrderReferenceId , $orderAmount , $sellerAuthNote , $captureNow = false , $syncAuth = false) {
// AuthorizationReferenceId
// The identifier for this authorization transaction that you specify. This identifier MUST BE unique for all your authorization transactions.
$authRefID = $amazonOrderReferenceId . '-' . substr(md5($amazonOrderReferenceId . time()),0,4);
// TransactionTimeout
// The number of minutes to allow the authorization to come back with a Successful response - if hit without a positive determination, authorization is declined.
if($syncAuth) {
$transactionTimeout = 0;
} else {
$transactionTimeout = 1440; // API Default
}
// CaptureNow
// Automagically capture funds upon successful Authorization
$captureNow = ($captureNow) ? "true" : "false";
$mwsResponse = $this->apiRequest("Authorize","POST",array("AmazonOrderReferenceId"=>$amazonOrderReferenceId,"AuthorizationAmount.Amount"=>$orderAmount,"AuthorizationAmount.CurrencyCode"=>"USD","AuthorizationReferenceId"=>$authRefID,"SellerAuthorizationNote"=>$sellerAuthNote,"CaptureNow"=>$captureNow,"TransactionTimeout"=>$transactionTimeout));
$this->lastResponse = $mwsResponse;
if($mwsResponse->getHttpCode() == "200") {
return true;
} else {
return false;
}
}
/* authorizeAndCapture
* default the sync auth and capture now values to true
*/
public function authorizeAndCapture($amazonOrderReferenceId , $orderAmount , $sellerAuthNote) {
return authorize($amazonOrderReferenceId , $orderAmount , $sellerAuthNote , true , true);
}
public function getLastResponse () {
return $this->lastResponse->getResponse();
}
public function apiRequest ($apiAction , $method , array $requestParams) {
$requestParams["Action"] = $apiAction;
$this->buildRequest($method,$requestParams);
error_log("requestParams to be submitted to MWS: " . print_r($requestParams,true));
return $this->httpPost();
}
private function buildRequest ($method , array $requestParams) {
$requestParams["AWSAccessKeyId"] = $this->accessKey;
$requestParams["SellerId"] = $this->merchantId;
$requestParams["SignatureVersion"] = "2";
$requestParams["SignatureMethod"] = $this->sigAlgorithm;
$requestParams["Version"] = $this->apiVersion;
$requestParams["Timestamp"] = date("c");
// add on request params
$this->paramList = $requestParams;
error_log("params: " . print_r($this->paramList,true));
// gen string to sign
$stringToSign = $this->getStringToSign($method);
// gen signature
$signature = $this->getSignature($stringToSign);
// add signature to request parameters
$this->paramList["Signature"] = $signature;
error_log("params: " . print_r($this->paramList,true));
}
private function getStringToSign ( $method) {
$endpoint = parse_url ($this->endpoint);
$stringToSign = $method . "\n" . $endpoint['host'] . "\n" . $this->url . "\n" . $this->buildQueryString();
error_log("string to sign: \n" . $stringToSign);
return $stringToSign;
}
private function buildQueryString () {
uksort($this->paramList, 'strcmp');
return $this->getParametersAsString();
}
private function getParametersAsString() {
$queryParameters = array();
foreach ($this->paramList as $key => $value) {
$queryParameters[] = $key . '=' . $this->customUrlEncode($value);
}
return implode('&', $queryParameters);
}
private function customUrlEncode($value) {
return str_replace('%7E', '~', rawurlencode($value));
}
private function getSignature($data) {
if ($this->sigAlgorithm === 'HmacSHA1') {
$hash = 'sha1';
} else if ($this->sigAlgorithm === 'HmacSHA256') {
$hash = 'sha256';
} else {
throw new Exception ("Non-supported signing method specified");
}
return base64_encode(
hash_hmac($hash, $data, $this->secretKey, true)
);
}
private function httpPost () {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->endpoint . $this->url);
curl_setopt($ch, CURLOPT_PORT, "443");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
# if a ca bundle is configured, use it as opposed to the default ca
# configured for the server
#if (!is_null($this->_merchantValues->getCaBundleFile())) {
# curl_setopt($ch, CURLOPT_CAINFO, $this->_merchantValues->getCaBundleFile());
#}
curl_setopt($ch, CURLOPT_USERAGENT, "PHP SDK/ Custom");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->getParametersAsString());
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
#if ($this->_config['ProxyHost'] != null && $this->_config['ProxyPort'] != -1)
#{
# curl_setopt($ch, CURLOPT_PROXY, $this->_config['ProxyHost'] . ':' . $this->_config['ProxyPort']);
#}
$response = curl_exec($ch);
if ($response === false) {
$error_msg = "Unable to post request, underlying exception of: (". curl_errno($ch) . ") " . curl_error($ch);
error_log("ERROR - " . $error_msg);
curl_close($ch);
throw new Exception($error_msg);
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE );
$headers = substr($response,0,strpos($response,"\r\n\r\n"));
$body = substr($response,strpos($response,"\r\n\r\n")+4);
$responseObj = new MWSResponse( $httpCode, $headers, $body );
error_log("response: " . $response);
curl_close($ch);
return $responseObj;
}
}
class MWSResponse {
private $httpCode;
private $headers;
private $response;
public function __construct($code,$headers,$response) {
$this->httpCode = $code;
$this->headers = $headers;
$this->response = $response;
}
public function getHttpCode () { return $this->httpCode; }
public function getHeaders () { return $this->headers; }
public function getResponse () { return $this->response; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment