OMS4 Push Mechanism

Last Updated:Apr 4,2024

What is OMS4 Push Mechanism and Why we need it.

Consider a situation that you are fetching new fulfillment tasks / shipping label, without OMS4 Push Mechanism, you are calling GetFulfillment Tasks/ GetShippingLabel API thousand times an hour(You may get throttled if your step over the limit.) by scheduler. Even you do that, you are not able to get your fulfillment task/shipping label once it occurred.

Now with Push Mechanism, OMS4 will send you a notification once new fulfillment task is created, which help you get your new fulfillment task in seconds.

Getting started with OMS4 Push Mechanism

Step1 : Prepare your callback url to receive notifications from OMS4 (By fulfillment point).

Step2: Understand push mechanism details include authorization, retry, etc.. and finish your coding.

Step3: Fill your url in and verify it.

Step4: Subscribe the messages.

This work-through document will take order notification as example.

Step1 : Prepare your callback url to receive notifications from OMS4.

It must be a https with CA certs.

Certification muse be authorized by CA. Self-signed certs are not acceptable.
Certs must be OV or EV. DV is not working.(know more about certs level : https://www.digicert.com/difference-between-dv-ov-and-ev-ssl-certificates).

Step2 : Understand push mechanism details include authorization, retry, etc.. and finish your coding.

After have your call back url, you need to know what a notification looks like. For example, fulfillment task / shipping label msg have two types of messages : fulfillment task message and shipping label message. fulfillment task message triggered when fulfillment task actions (create, xxxxx) happens. When shipping label has been generated, a shipping label message will be sent.

Header:Only you need to know is the 'Authorization' tag since that is the signature.
More details about it will be covered later.

1.fulfillment task message sample(trade order actions includes order create ..etc)

POST /example/uri HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 1238
Authorization: 34f7b258df045d4ed9341850ca85b866f34828fd7d51862f11137216294a894c

Request body
{
   "tenant_id":"1234567",  #Tenant ID
   "api_key":"XXXXXXXXXXX",  #API Key
   "webhook_type":"FP",
   "message_type":"new_ft",
   "data":{
      "ft_no":"FT0000000001", 
      "orig_order_no":"ORDER00000001", # one original order may contains multiple fulfillment tasks 
      "sales_channel":"XXXXX_SHOPEE_SG_SHOP01",
      "created_time":1603703663
   },
   "timestamp":1603766859530, #timestamp of push
}
2.shipping label message sample

POST /example/uri HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 1238
Authorization: 34f7b258df045d4ed9341850ca85b866f34828fd7d51862f11137216294a894c

Request body
{
   "tenant_id":"1234567",  #Tenant ID
   "api_key":"XXXXXXXXXXX",  #API Key
   "webhook_type":"FP",
   "message_type":"generated_shipping_label",
   "data":{
      "ft_no":"FT0000000001", 
      "orig_order_no":"ORDER00000001", # one original order may contains multiple fulfillment tasks 
      "sales_channel":"XXXXX_SHOPEE_SG_SHOP01",
      "fp_parcel_no":"FP_PARCEL_001",
      "tracking_no":"TRACK00000210",
      "obtained_time":1603703663
   },
   "timestamp":1603766859530, #timestamp of push
}

Questions you may have :

To make sure the request is sent from OMS4 and the request data is complete, OMS4 system will generate a signature and put it into request header. Client can reproduce the signature and compare it to the one receieved in message before consuming.

Signature is generated by Hex-encoded HMAC-SHA256.

/
Base = {your_app_key} + "{message_body_you_receieved}"
Secret = {your_app_Secret};
/
Authorization = HEX_ENCODE(HMAC-SHA256(Base, Secret));
Sample Java Code to reproduce the signature :

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

/**
 * Signature Util
 * @author Bowen
 * @date 2022/02/14
 */
public class SignatureUtil {
    private static final String HMAC_SHA256 = "HmacSHA256";

    private static final Logger LOGGER = LoggerFactory.getLogger(SignatureUtil.class);

    /**
     * Hmac-SHA256
     * @param base {AppKey} + {messageBody}
     * @param secret {AppSecret}
     * E.g.: AppKey = 123456, AppSecret = 3412gyo124goi3124
     * messageBody :{"tenant_id":"1234567", "message_type":0, "data":{...}..}
     *
     * base = "123456" + "{\"tenant_id\":\"1234567\", \"message_type\":0, "data":{...}..}"
     * secret = 3412gyo124goi3124
     * signature = getSignature(base, secret);
     * signature =  f3d2ca947f16a50b577c036adecd18bec126ea19cadedd59816e255d3b6104ab
     * @return signature
     */
    public static String getSignature(String base, String secret) {
        try {
            Mac sha256Hmac = Mac.getInstance(HMAC_SHA256);
            SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), HMAC_SHA256);
            sha256Hmac.init(secretKey);
            return byteArraytoHexString(sha256Hmac.doFinal(base.getBytes()));
        } catch (Exception e) {
            LOGGER.error("Failed to generate signature");
        }
        return null;

    }

    /**
     * Hex Encode
     * @param bytes
     * @return
     */
    private static String byteArraytoHexString(byte[] bytes) {
        if(bytes == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        String stmp;
        for (byte aByte : bytes) {
            stmp = Integer.toHexString(aByte & 0XFF);
            if (stmp.length() == 1) {
                sb.append('0');
            }
            sb.append(stmp);
        }
        return sb.toString().toLowerCase();
    }
}

Sucess acknowledage and retry :
You need to ack with Http status code 200 with in 2000ms
If you fail to do 1, server will retry sending the message after 30 mins.
If retry fails again, server will retry in another 30 mins.
if you fail more than 12 times or you sucessfuly do 1 before 12 times, server will stop retrying.
Question you may have :

Once a message is sucessfully acked, server wont retry sending this message.

FAQ:

I need the IPs of push servers to do ip white-listing, can you guys provide the ips ?
OMS4 recommends to use signature on authorization header to check the origin of pushes. No further supports on IPs from OMS4.

Some fulfillment point message are missing.

  1. OMS4 has holding minute configuration, still hold in OMS4 part.
  2. previously failed , waiting for retry (interval times 30mins)

Would there be more webhook types / message types beside fulfillment point message ?
Yes, refer to Webhook Message Definition for details.

How to get the fulfillment tasks if all retries failed ?
You need to use /fulfillment_tasks/get API to get them. The recommend way of consuming the message is : Consume the fulfillment task messages, and pull the fulfillment tasks periodically to check if there is any missing. So called "consume push, but pull with low frequency to protect from missing"

Duplicate message pushed for same fulfillment task?
Small amount of duplicate message is normal. Message design is 'at least once push'. Idempotently consuming is required.

Does shipping label generated message will be pushed to Fulfillment Point system before new Fulfillment Task message reach?
Possible. Usually it shouldn't occur. But it may happen if Fulfillment Task message pushing keep fail.

© 2025 OMS4. all right reserved,powered by GitbookVersion: 1.13.0.20250320 Modify: 2024-04-04 13:58:52

results matching ""

    No results matching ""