Skip to content

Instantly share code, notes, and snippets.

@ziyadparekh
Created January 17, 2020 07:46
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 ziyadparekh/39062a21b8b83e69adb067a7b7076d03 to your computer and use it in GitHub Desktop.
Save ziyadparekh/39062a21b8b83e69adb067a7b7076d03 to your computer and use it in GitHub Desktop.
Safepay Shopify Plugin Flow Description

The plugin will work as follows:

  1. Ability to install the plugin through composer (or through any php package manager)
  2. Once installed, the user can configure the plugin with the following core settings: a) Enable/Disable b) Enable/Disable Sandbox Mode c) Enter Sandbox API Key d) Enter Sandbox Secret Key (with instructions on where to find it on the dashboard) e) Enter Production API Key f) Enter Production Secret Key (with instructions on where to find it on the dashboard)

When the customer reaches the payment step, selects pay with Safepay, and clicks Place Order, the plugin should follow the Shopify flow of creating an order in the system, generating an Order ID and then with the appropriate API key (whether its sandbox or production) make a POST request to Safepay to generate a Payment like so:

curl --location --request POST 'https://sandbox.api.getsafepay.com/order/v1/init' \
--header 'Content-Type: application/json' \
--data-raw '{
"client": "sec_c18b707b-bd0f-41fe-947a-e894adf81e20",
"amount": 1000.00,
"currency": "PKR",
"environment": "sandbox" ("sandbox" or "production" based on the plugin setting)
}'

This request will return the following response

{
  "data":{
    "token":"track_a323b3d5-c9e8-410f-9020-6f3a9395f13e",
    "created_at":"2019-12-23T20:28:54Z",
    "updated_at":"2019-12-23T20:28:54Z",
    "user":"",
    "billing":"",
    "client":"sec_c18b707b-bd0f-41fe-947a-e894adf81e20",
    "environment":"local",
    "state":"TRACKER_STARTED",
    "state_reason":"",
    "amount":10,
    "currency":"USD",
    "default_currency":"PKR",
    "conversion_rate":153.37580742
  },
  "status":{
    "errors":[

    ],
    "message":"success"
  }
}

Upon receiving the response extract the "token" property from the JSON payload and use it to construct the following URL like so:

const PRODUCTION_CHECKOUT_URL = "https://www.getsafepay.com/components";
const SANDBOX_CHECKOUT_URL = "https://sandbox.api.getsafepay.com/components";

function construct_url($order, $tracker="")
{
  $baseURL = $this->sandbox ? self::SANDBOX_CHECKOUT_URL : self::PRODUCTION_CHECKOUT_URL;
  $params = array(
    "env" => $this->sandbox ? "sandbox" : "production",
    "beacon" => $tracker,
    "source" => 'shopify',
    "order_id" => $order->get_id(),
    "success_url" => $this->get_success_url(),
    "cancel_url" => $this->get_cancel_url()
  );

  $baseURL = add_query_arg($params, $baseURL);

  return $baseURL;
}

Once the URL is constructed, redirect the user to this URL.

When the user is on the Safepay payment page, if he clicks on "Cancel Payment", Safepay will automatically redirect the user to the "cancel_url". The plugin should handle the Shopify order cancellation flow including marking the order as cancelled and redirecting the user back to the Checkout page.

If the user completes payment, Safepay will make a POST request via an HTML form with the "action" being the "success_url". The following body will be sent to the post request: Order ID (Shopify Order ID) Reference Code (Safepay Transaction Reference Code) Tracker (Safepay Transaction Tracker Token) Signature (Signed value to prove authenticity of transaction)

The plugin must use the appropriate secret key (whether sandbox or production) to verify the transaction using the following code as example:

public function validate_signature($tracker, $signature)
{
  $secret = $this->get_shared_secret();
  $signature_2 = hash_hmac('sha256', $tracker, $secret);
  if ($signature_2 === $signature) {
    return true;
  }
  return false;
}

If the signature fails validation, the plugin should mark the order as "review" and add a note saying the payment failed validation. Or the plugin should just cancel the order and redirect the customer back to the checkout page.

If the signature passes validation, the plugin should save the Safepay Reference Code & Safepay Tracker to the Shopify Order so that the store owner can reconcile the Order with the payment.

The plugin should then mark the order as complete and redirect the customer to the order confirmed page.

Please refer to the Official Safepay Wordpress plugin for details and code on how to achieve this. https://github.com/getsafepay/safepay-woocommerce

Also refer to the Official Safepay Wordpress Plugin on the wordpress registry for screenshots on how the admin settings should look like: https://wordpress.org/plugins/woo-safepay-gateway/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment