NAV Navbar
Curl Java C# Javascript Php Python Ruby Swift

Introduction

Tourpay API.

API Endpoint

Production

https://api.tourpay.co

Sandbox

https://sandbox-api.tourpay.co

Authentication Endpoint

Production

https://auth.marketengine.com

Sandbox

https://sandbox-auth.marketengine.com

Programming Library for developers to use

Java: OkHttp

C#: RestSharp

Javascript: XMLHttpRequest

Php: ext-curl

Python: Requests

Ruby: Native

Swift: NSURLSession

Authentication

The Tourpay In-store API uses OAuth2 for POS device authentication. The access token should be used to access the API.

The Tourpay In-store API expects the access token to be included in all API requests as a HTTP header that look likes the following:

Authorization: Bearer <AccessToken>

Get Access Token

Example Get Access Token Request:

curl -X POST \
  https://sandbox-auth.marketengine.com/connect/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials&client_id=TOURPAY-KEY-123456&client_secret=TOURPAY-SECRET-123456'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=123456&client_secret=TOURPAY-SECRET-123456");
Request request = new Request.Builder()
  .url("https://sandbox-auth.marketengine.com/connect/token")
  .post(body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .build();

Response response = client.newCall(request).execute();
var client = new RestClient("https://sandbox-auth.marketengine.com/connect/token");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("undefined", "grant_type=client_credentials&client_id=123456&client_secret=123456", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var data =
  "grant_type=client_credentials&client_id=TOURPAY-KEY-123456&client_secret=TOURPAY-SECRET-123456";

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox-auth.marketengine.com/connect/token");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("User-Agent", "PostmanRuntime/7.16.3");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://sandbox-auth.marketengine.com/connect/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "grant_type=client_credentials&client_id=TOURPAY-KEY-123456&client_secret=TOURPAY-SECRET-123456",
  CURLOPT_HTTPHEADER => array(
    "Content-Type: application/x-www-form-urlencoded"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://sandbox-auth.marketengine.com/connect/token"

payload = "grant_type=client_credentials&client_id=TOURPAY-KEY-123456&client_secret=TOURPAY-SECRET-123456"
headers = {
    'Content-Type': "application/x-www-form-urlencoded"
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
require 'uri'
require 'net/http'

url = URI("https://sandbox-auth.marketengine.com/connect/token")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/x-www-form-urlencoded'
request.body = "grant_type=client_credentials&client_id=TOURPAY-KEY-123456&client_secret=TOURPAY-SECRET-123456"

response = http.request(request)
puts response.read_body
import Foundation

let headers = [
  "Content-Type": "application/x-www-form-urlencoded"
]

let postData = NSMutableData(data: "grant_type=client_credentials".data(using: String.Encoding.utf8)!)
postData.append("&client_id=TOURPAY-KEY-123456".data(using: String.Encoding.utf8)!)
postData.append("&client_secret=TOURPAY-SECRET-123456".data(using: String.Encoding.utf8)!)

let request = NSMutableURLRequest(url: NSURL(string: "https://sandbox-auth.marketengine.com/connect/token")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Response:

{
  "token_type": "Bearer",
  "expires_in": 3299,
  "access_token": "ff88f47bc137b4fd5eef5152b292e3ca"
}

This endpoint retrieves access token.

HTTP Request

POST /connect/token to Authentication Endpoint

HTTP Headers

Parameter Description
Content-Type application/x-www-form-urlencoded

Client Credentials

Parameter Description
client_id Get from merchant portal. Eg. TOURPAY-KEY-123456
client_secret Get from merchant portal. Eg. TOURPAY-SECRET-123456

Arguments

Parameter Description
grant_type client_credentials

Response

Parameter Type Description
token_type string Bearer
expires_in int The amount of time in seconds the token lives
access_token string Access token used to access Tourpay API

Create Order

Example Create Order Request:

curl "https://sandbox-api.tourpay.co/api/v1/en/offline/order/pay"
  -X PUT
  -H 'Authorization: Bearer <AccessToken>'
  -H 'Content-Type: application/json'
  -H 'User-Agent: Merchant/{MerchantCode}'
  -d '{
        "membershipNumber": "31358245",
        "orderId": "EDB4857B-B861-474E-9EC1-05B831400018",
        "TotalAmount":2.9,
        "currency": "AUD",
        "discounts": [
          {
            "displayName": "10% off",
            "amount": 1.49
          },
            {
            "displayName": "$11 voucher",
            "amount": 1
          },
            {
            "displayName": "adjustment",
            "amount": 1.59
          }
        ],
        "items": [
          {
            "name": "Product A",
            "sku": "Sku-1",
            "quantity": 1,
            "price": 0.99
          },
            {
            "name": "Product B",
            "sku": "Sku-2",
            "quantity": 1,
            "price":2.00
          },
            {
            "name": "Product C",
            "sku": "Sku-3",
            "quantity": 1,
            "price": 3.99
          }
        ],
        "description": "Description 1234567",
        "paymentCode": "284983395631123456",
        "deviceId": "Sn12345"
      }'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"membershipNumber\": \"72945681\",\n    \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831400018\",\n    \"TotalAmount\": 2.9,\n    \"currency\": \"AUD\",\n    \"discounts\": [\n        {\n            \"displayName\": \"10% off\",\n            \"amount\": 1.49\n        },\n        {\n            \"displayName\": \"$10 off voucher\",\n            \"amount\": 1\n        },\n        {\n            \"displayName\": \"adjustment\",\n            \"amount\": 1.59\n        }\n    ],\n    \"items\": [\n        {\n            \"name\": \"Dyson-Light Ball Multi Floor upright vacuum - Red\",\n            \"sku\": \"281282-01\",\n            \"quantity\": 1,\n            \"price\": 0.99\n        },\n        {\n            \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\n            \"sku\": \"KBJX2001BK\",\n            \"quantity\": 1,\n            \"price\": 2\n        },\n        {\n            \"name\": \"Breville-the Barista Express\",\n            \"sku\": \"BES870CRN\",\n            \"quantity\": 1,\n            \"price\": 3.99\n        }\n    ],\n    \"description\": \"Myer Appliances Order via Alipay\",\n    \"paymentCode\": \"284658745306743583\",\n    \"deviceId\": \"Sunmi POS 1\"\n}");
Request request = new Request.Builder()
  .url("https://sandbox-api.tourpay.co/api/v1/en/offline/order/pay")
  .put(body)
  .addHeader("Content-Type", "application/json")
  .addHeader("User-Agent", "Merchant/{MerchantCode}")
  .addHeader("Authorization", "Bearer <AccessToken>")
  .build();

Response response = client.newCall(request).execute();
var client = new RestClient("https://sandbox-api.tourpay.co/api/v1/en/offline/order/pay");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <AccessToken>");
request.AddHeader("User-Agent", "Merchant/{MerchantCode}");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("undefined", "{\n    \"membershipNumber\": \"72945681\",\n    \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831400018\",\n    \"TotalAmount\": 2.9,\n    \"currency\": \"AUD\",\n    \"discounts\": [\n        {\n            \"displayName\": \"10% off\",\n            \"amount\": 1.49\n        },\n        {\n            \"displayName\": \"$10 off voucher\",\n            \"amount\": 1\n        },\n        {\n            \"displayName\": \"adjustment\",\n            \"amount\": 1.59\n        }\n    ],\n    \"items\": [\n        {\n            \"name\": \"Dyson-Light Ball Multi Floor upright vacuum - Red\",\n            \"sku\": \"281282-01\",\n            \"quantity\": 1,\n            \"price\": 0.99\n        },\n        {\n            \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\n            \"sku\": \"KBJX2001BK\",\n            \"quantity\": 1,\n            \"price\": 2\n        },\n        {\n            \"name\": \"Breville-the Barista Express\",\n            \"sku\": \"BES870CRN\",\n            \"quantity\": 1,\n            \"price\": 3.99\n        }\n    ],\n    \"description\": \"Myer Appliances Order via Alipay\",\n    \"paymentCode\": \"284658745306743583\",\n    \"deviceId\": \"Sunmi POS 1\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var data = JSON.stringify({
  membershipNumber: "72945681",
  orderId: "EDB4857B-B861-474E-9EC1-05B831400018",
  TotalAmount: 2.9,
  currency: "AUD",
  discounts: [
    {
      displayName: "10% off",
      amount: 1.49
    },
    {
      displayName: "$10 off voucher",
      amount: 1
    },
    {
      displayName: "adjustment",
      amount: 1.59
    }
  ],
  items: [
    {
      name: "Dyson-Light Ball Multi Floor upright vacuum - Red",
      sku: "281282-01",
      quantity: 1,
      price: 0.99
    },
    {
      name: "Delonghi-Brilliante Exclusive kettle: Black",
      sku: "KBJX2001BK",
      quantity: 1,
      price: 2
    },
    {
      name: "Breville-the Barista Express",
      sku: "BES870CRN",
      quantity: 1,
      price: 3.99
    }
  ],
  description: "Myer Appliances Order via Alipay",
  paymentCode: "284658745306743583",
  deviceId: "Sunmi POS 1"
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://sandbox-api.tourpay.co/api/v1/en/offline/order/pay");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("User-Agent", "Merchant/{MerchantCode}");
xhr.setRequestHeader("Authorization", "Bearer <AccessToken>");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://sandbox-api.tourpay.co/api/v1/en/offline/order/pay",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\n    \"membershipNumber\": \"72945681\",\n    \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831400018\",\n    \"TotalAmount\": 2.9,\n    \"currency\": \"AUD\",\n    \"discounts\": [\n        {\n            \"displayName\": \"10% off\",\n            \"amount\": 1.49\n        },\n        {\n            \"displayName\": \"$10 off voucher\",\n            \"amount\": 1\n        },\n        {\n            \"displayName\": \"adjustment\",\n            \"amount\": 1.59\n        }\n    ],\n    \"items\": [\n        {\n            \"name\": \"Dyson-Light Ball Multi Floor upright vacuum - Red\",\n            \"sku\": \"281282-01\",\n            \"quantity\": 1,\n            \"price\": 0.99\n        },\n        {\n            \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\n            \"sku\": \"KBJX2001BK\",\n            \"quantity\": 1,\n            \"price\": 2\n        },\n        {\n            \"name\": \"Breville-the Barista Express\",\n            \"sku\": \"BES870CRN\",\n            \"quantity\": 1,\n            \"price\": 3.99\n        }\n    ],\n    \"description\": \"Myer Appliances Order via Alipay\",\n    \"paymentCode\": \"284658745306743583\",\n    \"deviceId\": \"Sunmi POS 1\"\n}",
  CURLOPT_HTTPHEADER => array(
    "Authorization: Bearer <AccessToken>",
    "Content-Type: application/json",
    "User-Agent: Merchant/{MerchantCode}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://sandbox-api.tourpay.co/api/v1/en/offline/order/pay"

payload = "{\n    \"membershipNumber\": \"72945681\",\n    \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831400018\",\n    \"TotalAmount\": 2.9,\n    \"currency\": \"AUD\",\n    \"discounts\": [\n        {\n            \"displayName\": \"10% off\",\n            \"amount\": 1.49\n        },\n        {\n            \"displayName\": \"$10 off voucher\",\n            \"amount\": 1\n        },\n        {\n            \"displayName\": \"adjustment\",\n            \"amount\": 1.59\n        }\n    ],\n    \"items\": [\n        {\n            \"name\": \"Dyson-Light Ball Multi Floor upright vacuum - Red\",\n            \"sku\": \"281282-01\",\n            \"quantity\": 1,\n            \"price\": 0.99\n        },\n        {\n            \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\n            \"sku\": \"KBJX2001BK\",\n            \"quantity\": 1,\n            \"price\": 2\n        },\n        {\n            \"name\": \"Breville-the Barista Express\",\n            \"sku\": \"BES870CRN\",\n            \"quantity\": 1,\n            \"price\": 3.99\n        }\n    ],\n    \"description\": \"Myer Appliances Order via Alipay\",\n    \"paymentCode\": \"284658745306743583\",\n    \"deviceId\": \"Sunmi POS 1\"\n}"
headers = {
    'Content-Type': "application/json",
    'User-Agent': "Merchant/{MerchantCode}",
    'Authorization': "Bearer <AccessToken>"
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
require 'uri'
require 'net/http'

url = URI("https://sandbox-api.tourpay.co/api/v1/en/offline/order/pay")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Put.new(url)
request["Content-Type"] = 'application/json'
request["User-Agent"] = 'Merchant/{MerchantCode}'
request["Authorization"] = 'Bearer <AccessToken>'
request.body = "{\n    \"membershipNumber\": \"72945681\",\n    \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831400018\",\n    \"TotalAmount\": 2.9,\n    \"currency\": \"AUD\",\n    \"discounts\": [\n        {\n            \"displayName\": \"10% off\",\n            \"amount\": 1.49\n        },\n        {\n            \"displayName\": \"$10 off voucher\",\n            \"amount\": 1\n        },\n        {\n            \"displayName\": \"adjustment\",\n            \"amount\": 1.59\n        }\n    ],\n    \"items\": [\n        {\n            \"name\": \"Dyson-Light Ball Multi Floor upright vacuum - Red\",\n            \"sku\": \"281282-01\",\n            \"quantity\": 1,\n            \"price\": 0.99\n        },\n        {\n            \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\n            \"sku\": \"KBJX2001BK\",\n            \"quantity\": 1,\n            \"price\": 2\n        },\n        {\n            \"name\": \"Breville-the Barista Express\",\n            \"sku\": \"BES870CRN\",\n            \"quantity\": 1,\n            \"price\": 3.99\n        }\n    ],\n    \"description\": \"Myer Appliances Order via Alipay\",\n    \"paymentCode\": \"284658745306743583\",\n    \"deviceId\": \"Sunmi POS 1\"\n}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = [
  "Content-Type": "application/json",
  "User-Agent": "Merchant/{MerchantCode}",
  "Authorization": "Bearer <AccessToken>"
]
let parameters = [
  "membershipNumber": "72945681",
  "orderId": "EDB4857B-B861-474E-9EC1-05B831400018",
  "TotalAmount": 2.9,
  "currency": "AUD",
  "discounts": [
    [
      "displayName": "10% off",
      "amount": 1.49
    ],
    [
      "displayName": "$10 off voucher",
      "amount": 1
    ],
    [
      "displayName": "adjustment",
      "amount": 1.59
    ]
  ],
  "items": [
    [
      "name": "Dyson-Light Ball Multi Floor upright vacuum - Red",
      "sku": "281282-01",
      "quantity": 1,
      "price": 0.99
    ],
    [
      "name": "Delonghi-Brilliante Exclusive kettle: Black",
      "sku": "KBJX2001BK",
      "quantity": 1,
      "price": 2
    ],
    [
      "name": "Breville-the Barista Express",
      "sku": "BES870CRN",
      "quantity": 1,
      "price": 3.99
    ]
  ],
  "description": "Myer Appliances Order via Alipay",
  "paymentCode": "284658745306743583",
  "deviceId": "Sunmi POS 1"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://sandbox-api.tourpay.co/api/v1/en/offline/order/pay")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Response:

{
  "value": {
    "orderId": "EDB4857B-B861-474E-9EC1-05B831400018",
    "code": "PAID",
    "totalAmount": 1.0,
    "currency": "AUD",
    "paymentType": "WECHAT",
    "payTime": "2019-07-23 10:04:35",
    "invoiceNumber": "1565573720"
  },
  "isSuccess": true,
  "errors": []
}

This endpoint creates an order that is used to initiate the payment process.

HTTP Request

PUT /api/v1/{lang}/offline/order/pay to API Endpoint

HTTP Headers

Parameter Description
Content-Type application/json
Accept application/json
User-Agent Merchant/{MerchantCode}

Path Variable

Parameter Description
lang Either "en" or "zh-cn"

Arguments

Parameter Type Description
membershipNumber string Required User’s membership number
orderId Guid Required Order Id
totalAmount decimal Required Total payable amount for order(2 decimal places)
currency string Required "AUD"
discounts Discount[] Required An array of discounts
items Item[] Required An array of order items
description string Optional Order description
paymentCode string Required The digits scanned from customers Alipay or Wechat pay payment code
deviceId string Required Device unique identifier

Order Discount Object

Parameter Type Description
displayName string Required Discount display name
amount decimal Required Discount amount

Order Item Object

Parameter Type Description
name string Required Product name
sku decimal Required Product unique identifier
quantity int Required The quantity of the item
price decimal Required The unit price(2 decimal places)
imageUrl decimal Optional The product image url

Response

Parameter Type Description
isSuccess bool Whether this order has succeeded
errors Error[] Error message list
value Value Payment detail

Order Value Object

Parameter Type Description
orderId Guid Order Id
code string Order status. See below success code
totalAmount decimal Order amount
currency string Currency in IOS_4217 format. Only "AUD" is supported at current stage.
paymentType string Channel. "ALIPAY" or "WECHAT"
payTime string Time when order is paid(yyyy-MM-dd HH:mm:ss, UTC+10)
invoiceNumber Guid The tourpay invoice number that are displayed on the invoice.

Order Succ Code

Parameter Description
PROCESSING This order is in processing
PAID The payment processed successfully
PARTIAL_REFUND Portion of fund was returned
FULL_REFUND The order full amount are refunded

Order Error Code

Parameter Description
IVALID_PARAMETERS The request body data is invalid
CONFLICT_REQUEST The order with the same order id is being processing, you should wait another request finish
IVALID_MERCHANTCODE The merchant code is incorrect, or User-Agent is missing from request header.
IVALID_ORDER_AMOUNT The given amount does not equal to sum of all items less amount of discounts
INVALID_MEMBER_NUMBER The membership number is incorrect
TIMEOUT The request is abort due to high latency between bank and Tourpay
PAYMENT_FAIL The payment is failed. Many reasons can cause this, e.g. invalid payment code.
SYSTEM_ERROR Internal system error

Check Order Status

Example Check Order Status Request:

curl -X GET \
  https://sandbox-api.tourpay.co/api/v1/en/offline/order/status \
  -H 'Authorization: Bearer <AccessToken>' \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Merchant/{MerchantCode}' \
  -d '{
    "orderId": "5999c1e9-f081-4483-a03d-3c6c4d29bb78"
}'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\"\n}");
Request request = new Request.Builder()
  .url("https://sandbox-api.tourpay.co/api/v1/en/offline/order/status")
  .get()
  .addHeader("User-Agent", "Merchant/{MerchantCode}")
  .addHeader("Authorization", "Bearer <AccessToken>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var client = new RestClient("https://sandbox-api.tourpay.co/api/v1/en/offline/order/status");
var request = new RestRequest(Method.GET);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer <AccessToken>");
request.AddHeader("User-Agent", "Merchant/{MerchantCode}");
request.AddParameter("undefined", "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var data = JSON.stringify({
  orderId: "5999c1e9-f081-4483-a03d-3c6c4d29bb78"
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open(
  "GET",
  "https://sandbox-api.tourpay.co/api/v1/en/offline/order/status"
);
xhr.setRequestHeader("User-Agent", "Merchant/{MerchantCode}");
xhr.setRequestHeader("Authorization", "Bearer <AccessToken>");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://sandbox-api.tourpay.co/api/v1/en/offline/order/status",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_POSTFIELDS => "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\"\n}",
  CURLOPT_HTTPHEADER => array(
    "Authorization: Bearer <AccessToken>",
    "Content-Type: application/json",
    "User-Agent: Merchant/{MerchantCode}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://sandbox-api.tourpay.co/api/v1/en/offline/order/status"

payload = "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\"\n}"
headers = {
    'User-Agent': "Merchant/{MerchantCode}",
    'Authorization': "Bearer <AccessToken>",
    'Content-Type': "application/json"
    }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
require 'uri'
require 'net/http'

url = URI("https://sandbox-api.tourpay.co/api/v1/en/offline/order/status")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["User-Agent"] = 'Merchant/{MerchantCode}'
request["Authorization"] = 'Bearer <AccessToken>'
request["Content-Type"] = 'application/json'
request.body = "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\"\n}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = [
  "User-Agent": "Merchant/{MerchantCode}",
  "Authorization": "Bearer <AccessToken>",
  "Content-Type": "application/json"
]
let parameters = ["orderId": "5999c1e9-f081-4483-a03d-3c6c4d29bb78"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://sandbox-api.tourpay.co/api/v1/en/offline/order/status")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Response:

{
  "value": {
    "orderId": "5999c1e9-f081-4483-a03d-3c6c4d29bb78",
    "code": "PAID",
    "totalAmount": 1.0,
    "currency": "AUD",
    "paymentType": "WECHAT",
    "payTime": "2019-07-23 10:04:35"
  },
  "isSuccess": true,
  "errors": []
}

This endpoint is used to get order status.

HTTP Request

GET /api/v1/{lang}/offline/order/status to API Endpoint

HTTP Headers

Parameter Description
Content-Type application/json
Accept application/json
User-Agent Merchant/{MerchantCode}

Path Variable

Parameter Description
lang Either "en" or "zh-cn"

Arguments

Parameter Type Description
orderId Guid Required Order Id

Response

Parameter Type Description
isSuccess bool Whether this order has succeeded
errors Error[] Error message list
value Value Order status detail

Order Status Value Object

Parameter Type Description
orderId Guid Order Id
code string Order status. See below success code
totalAmount decimal Order amount
currency string Currency in IOS_4217 format. Only "AUD" is supported at current stage.
paymentType string Channel. "ALIPAY" or "WECHAT"
payTime string Time when order is paid(yyyy-MM-dd HH:mm:ss, UTC+10)
invoiceNumber Guid The tourpay invoice number that are displayed on the invoice.

Order Status Succ Code

Parameter Description
PROCESSING This order is in processing
PAID The payment processed successfully
PARTIAL_REFUND Portion of fund was returned
FULL_REFUND The order full amount are refunded

Order Status Error Code

Parameter Description
IVALID_PARAMETERS The request body data is invalid
CONFLICT_REQUEST The order with the same order id is being processing, you should wait another request finish
IVALID_MERCHANTCODE The merchant code is incorrect, or User-Agent is missing from request header.
ORDER_NOT_FOUND The order id can’t be found in the system
TIMEOUT The request is abort due to high latency between bank and Tourpay
PAYMENT_FAIL The payment is failed. Many reasons can cause this, e.g. invalid payment code.
SYSTEM_ERROR Internal system error

Refund

Example Create Refund Request:

curl -X PUT \
  https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund \
  -H 'Authorization: Bearer <AccessToken>' \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Merchant/{MerchantCode}' \
  -d '{
 "orderId": "EDB4857B-B861-474E-9EC1-05B831425C42",
 "totalAmount": 2.9,
 "items": [{
     "name": "Delonghi-Brilliante Exclusive kettle: Black",
     "sku": "KBJX2001BK",
     "quantity": 1,
     "price": 2.9
 }]
}'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831425C42\",\r\n \"totalAmount\": 2.9,\r\n \"items\": [{\r\n     \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\r\n     \"sku\": \"KBJX2001BK\",\r\n     \"quantity\": 1,\r\n     \"price\": 2.9\r\n     \r\n }]\r\n}");
Request request = new Request.Builder()
  .url("https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund")
  .put(body)
  .addHeader("Content-Type", "application/json")
  .addHeader("User-Agent", "Merchant/{MerchantCode}")
  .addHeader("Authorization", "Bearer <AccessToken>")
  .build();

Response response = client.newCall(request).execute();
var client = new RestClient("https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <AccessToken>");
request.AddHeader("User-Agent", "Merchant/{MerchantCode}");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("undefined", "{\r\n \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831425C42\",\r\n \"totalAmount\": 2.9,\r\n \"items\": [{\r\n     \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\r\n     \"sku\": \"KBJX2001BK\",\r\n     \"quantity\": 1,\r\n     \"price\": 2.9\r\n     \r\n }]\r\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var data = JSON.stringify({
  orderId: "EDB4857B-B861-474E-9EC1-05B831425C42",
  totalAmount: 2.9,
  items: [
    {
      name: "Delonghi-Brilliante Exclusive kettle: Black",
      sku: "KBJX2001BK",
      quantity: 1,
      price: 2.9
    }
  ]
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open(
  "PUT",
  "https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund"
);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("User-Agent", "Merchant/{MerchantCode}");
xhr.setRequestHeader("Authorization", "Bearer <AccessToken>");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\r\n \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831425C42\",\r\n \"totalAmount\": 2.9,\r\n \"items\": [{\r\n     \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\r\n     \"sku\": \"KBJX2001BK\",\r\n     \"quantity\": 1,\r\n     \"price\": 2.9\r\n     \r\n }]\r\n}",
  CURLOPT_HTTPHEADER => array(
    "Authorization: Bearer <AccessToken>",
    "Content-Type: application/json",
    "User-Agent: Merchant/{MerchantCode}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund"

payload = "{\r\n \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831425C42\",\r\n \"totalAmount\": 2.9,\r\n \"items\": [{\r\n     \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\r\n     \"sku\": \"KBJX2001BK\",\r\n     \"quantity\": 1,\r\n     \"price\": 2.9\r\n     \r\n }]\r\n}"
headers = {
    'Content-Type': "application/json",
    'User-Agent': "Merchant/{MerchantCode}",
    'Authorization': "Bearer <AccessToken>"
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
require 'uri'
require 'net/http'

url = URI("https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Put.new(url)
request["Content-Type"] = 'application/json'
request["User-Agent"] = 'Merchant/{MerchantCode}'
request["Authorization"] = 'Bearer <AccessToken>'
request.body = "{\r\n \"orderId\": \"EDB4857B-B861-474E-9EC1-05B831425C42\",\r\n \"totalAmount\": 2.9,\r\n \"items\": [{\r\n     \"name\": \"Delonghi-Brilliante Exclusive kettle: Black\",\r\n     \"sku\": \"KBJX2001BK\",\r\n     \"quantity\": 1,\r\n     \"price\": 2.9\r\n     \r\n }]\r\n}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = [
  "Content-Type": "application/json",
  "User-Agent": "Merchant/{MerchantCode}",
  "Authorization": "Bearer <AccessToken>"
]
let parameters = [
  "orderId": "EDB4857B-B861-474E-9EC1-05B831425C42",
  "totalAmount": 2.9,
  "items": [
    [
      "name": "Delonghi-Brilliante Exclusive kettle: Black",
      "sku": "KBJX2001BK",
      "quantity": 1,
      "price": 2.9
    ]
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Response:

{
  "value": {
    "orderId": "EDB4857B-B861-474E-9EC1-05B831425C42",
    "refundId": "1564707594",
    "code": "REFUND_SUCCESS",
    "totalAmount": 2.8,
    "currency": "AUD"
  },
  "isSuccess": true,
  "errors": []
}

This endpoint is used to create a refund request.

HTTP Request

PUT /api/v1/{lang}/offline/order/refund to API Endpoint

HTTP Headers

Parameter Description
Content-Type application/json
Accept application/json
User-Agent Merchant/{MerchantCode}

Path Variable

Parameter Description
lang Either "en" or "zh-cn"

Arguments

Parameter Type Description
orderId Guid Required Order Id
totalAmount decimal Required Total payable amount for order(2 decimal places)
items Item[] Required An array of order items

Refund Item Object

Parameter Type Description
name string Required Product name
sku decimal Required Product unique identifier
quantity int Required The quantity of the item
price decimal Required The unit price(2 decimal places)
imageUrl decimal Optional The product image url

Response

Parameter Type Description
isSuccess bool Whether this order has succeeded
errors Error[] Error message list
value Value Payment detail

Refund Value Object

Parameter Type Description
orderId Guid Order Id
refundId string Refund Id
code string Order status. See below success code
totalAmount decimal Order amount
currency string Currency in IOS_4217 format. Only "AUD" is supported at current stage.

Refund Succ Code

Parameter Description
PROCESSING This order is in processing
REFUND_SUCCESS The refund processed successfully
INVESTIGATION_REQUIRED Please contact us if you receive this error message

Refund Error Code

Parameter Description
IVALID_PARAMETERS The request body data is invalid
CONFLICT_REQUEST The order with the same order id is being processing, you should wait another request finish
IVALID_MERCHANTCODE The merchant code is incorrect, or User-Agent is missing from request header.
IVALID_REFUND_AMOUNT The given amount does not equal to sum of all items
ORDER_NOT_FOUND The order id can’t be found in the system
TIMEOUT The request is abort due to high latency between bank and Tourpay
REFUND_FAIL The refund is failed.
SYSTEM_ERROR Internal system error

Check Refund Status

Example Check Refund Status Request:

curl -X GET \
  https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund/status \
  -H 'Authorization: Bearer <AccessToken>' \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Merchant/{MerchantCode}' \
  -d '{
    "orderId": "5999c1e9-f081-4483-a03d-3c6c4d29bb78",
    "refundId": 1564651562
}'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\",\n    \"refundId\": 1564651562\n}");
Request request = new Request.Builder()
  .url("https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund/status")
  .get()
  .addHeader("User-Agent", "Merchant/{MerchantCode}")
  .addHeader("Authorization", "Bearer <AccessToken>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var client = new RestClient("https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund/status");
var request = new RestRequest(Method.GET);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer <AccessToken>");
request.AddHeader("User-Agent", "Merchant/{MerchantCode}");
request.AddParameter("undefined", "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\",\n    \"refundId\": 1564651562\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var data = JSON.stringify({
  orderId: "5999c1e9-f081-4483-a03d-3c6c4d29bb78",
  refundId: 1564651562
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open(
  "GET",
  "https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund/status"
);
xhr.setRequestHeader("User-Agent", "Merchant/{MerchantCode}");
xhr.setRequestHeader("Authorization", "Bearer <AccessToken>");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund/status",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_POSTFIELDS => "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\",\n    \"refundId\": 1564651562\n}",
  CURLOPT_HTTPHEADER => array(
    "Authorization: Bearer <AccessToken>",
    "Content-Type: application/json",
    "User-Agent: Merchant/{MerchantCode}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import requests

url = "https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund/status"

payload = "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\",\n    \"refundId\": 1564651562\n}"
headers = {
    'User-Agent': "Merchant/{MerchantCode}",
    'Authorization': "Bearer <AccessToken>",
    'Content-Type': "application/json"
    }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
require 'uri'
require 'net/http'

url = URI("https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund/status")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["User-Agent"] = 'Merchant/{MerchantCode}'
request["Authorization"] = 'Bearer <AccessToken>'
request["Content-Type"] = 'application/json'
request.body = "{\n    \"orderId\": \"5999c1e9-f081-4483-a03d-3c6c4d29bb78\",\n    \"refundId\": 1564651562\n}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = [
  "User-Agent": "Merchant/{MerchantCode}",
  "Authorization": "Bearer <AccessToken>",
  "Content-Type": "application/json"
]
let parameters = [
  "orderId": "5999c1e9-f081-4483-a03d-3c6c4d29bb78",
  "refundId": 1564651562
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://sandbox-api.tourpay.co/api/v1/en/offline/order/refund/status")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Response:

{
    "value": {
        "orderId": "5999c1e9-f081-4483-a03d-3c6c4d29bb78",
        "refundId": "1564651562"
        "code": "PAID",
        "totalAmount": 1.0,
        "currency": "AUD",
        "paymentType": "WECHAT",
        "payTime": "2019-07-23 10:04:35"
    },
    "isSuccess": true,
    "errors": []
}

This endpoint is used to get order status.

HTTP Request

GET /api/v1/{lang}/offline/order/refund/status to API Endpoint

HTTP Headers

Parameter Description
Content-Type application/json
Accept application/json
User-Agent Merchant/{MerchantCode}

Path Variable

Parameter Description
lang Either "en" or "zh-cn"

Arguments

Parameter Type Description
orderId Guid Required Order Id
refundId long Required Returned in the response Which was returned in the response

Response

Parameter Type Description
isSuccess bool Whether this order has succeeded
errors Error[] Error message list
value Value Order status detail

Refund Status Value Object

Parameter Type Description
orderId Guid Order Id
refundId string Refund Id
code string Order status. See below success code
totalAmount decimal Order amount
currency string Currency in IOS_4217 format. Only "AUD" is supported at current stage.
paymentType string Channel. "ALIPAY" or "WECHAT"
payTime string Time when order is paid(yyyy-MM-dd HH:mm:ss, UTC+10)

Refund Status Succ Object

Parameter Description
PROCESSING The refund is being processing
REFUND_SUCCESS The refund processed successfully
INVESTIGATION_REQUIRED Please contact us if you receive this error message

Refund Status Error Code

Parameter Description
IVALID_PARAMETERS The request body data is invalid
CONFLICT_REQUEST The order with the same order id is being processing, you should wait another request finish
IVALID_MERCHANTCODE The merchant code is incorrect, or User-Agent is missing from request header.
REFUND_NOT_FOUND The refund id can’t be found in the system with associated order id
TIMEOUT The request is abort due to high latency between bank and Tourpay
REFUND_FAIL The refund is failed. Many reasons can cause this.
SYSTEM_ERROR Internal system error