本文へスキップ

方法 5:API 連携

自社開発の受注システムがある場合や、他の 4 つでは要件を満たせない場合に選びます。モール連携・ERP 連携との違いはひとつだけ、この方法だけコードを書く必要があることです。 件数が多いだけで開発は避けたいなら方法 2:一括インポート、受注がモールや外部 ERP にあるなら方法 3〜4:自動連携へ。

API を選ぶべきケース

受注がどこにあるかおすすめ
Amazon・Shopify・楽天などの販売モールモール連携、開発不要
利用中の外部 ERPERP 連携、開発不要
件数が多くて手入力が追いつかないだけ一括インポート、開発不要
自社開発の受注システム、項目やタイミングを作り込みたいAPI 連携

事前に用意するもの

必要なもの入手先
appKey / appSecretOMS 右上のアバター → API信息(API 情報)/userCenter/apiKeys
API ドキュメントhttps://apidoc-oms.xlwms.com/
ベース URLhttps://api.xlwms.com/openapi/

この画面は App Key / App Secret / 備考 / 作成日時 / 作成者 の一覧で、鍵は既定でマスク表示されます。右上には**開発験签工具(署名検証ツール)**のボタンがあり、公式の検証ページへ直接移動できます。

appKey と appSecret の取得場所
注意 appSecret は署名鍵です。自社サーバー側にのみ保管し、フロントエンドやアプリに埋め込まないでください。

リクエストの署名

すべてのリクエストに署名 authcode が必要で、アルゴリズムは HmacSHA256 です。

  1. 業務パラメータ data の項目を**辞書順(大文字小文字を区別しない)**に並べ替えて JSON 化する
  2. appKey + 並べ替えた datareqTime の順に区切り文字なしで連結する
  3. appSecret を鍵として HmacSHA256 を計算し、16 進数文字列に変換したものが authcode

渡し方にも注意が必要です。authcode は URL クエリ、appKey / data / reqTime は POST ボディで送ります。

パラメータ位置説明
authcodeURL クエリ上記で算出した署名
appKeyPOST ボディOMS 管理画面で発行された key
reqTimePOST ボディ10 桁の UNIX タイムスタンプ(秒)
dataPOST ボディ業務パラメータ。作成 API では配列
重要 reqTime が 5 分を超えたリクエストはサーバー側で拒否されます。 署名を使い回さず、サーバーの時刻ずれにも注意してください。

署名が合わないときは公式の検証ツール

ドキュメントサイトにオンライン検証ツールがあります。appKeydatareqTime を貼り付けて比較すれば、並べ替え・シリアライズ・連結のどこで食い違っているかがすぐ分かります。

署名のサンプルコード

ドキュメントに沿った最小構成です。接続テストの前に必ず公式の検証ツールで一度突き合わせてください。

js
// Node.js 18+
import crypto from 'node:crypto'

function sign({ appKey, appSecret, data, reqTime }) {
  // 1. data 内字段按字典序(不区分大小写)排序后序列化
  const sortedData = JSON.stringify(sortKeys(data))
  // 2. 三段直接拼接,没有分隔符
  const raw = `${appKey}${sortedData}${reqTime}`
  // 3. HmacSHA256 后转十六进制
  return crypto.createHmac('sha256', appSecret).update(raw).digest('hex')
}

function sortKeys(value) {
  if (Array.isArray(value)) return value.map(sortKeys)
  if (value && typeof value === 'object') {
    return Object.fromEntries(
      Object.keys(value)
        .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
        .map((k) => [k, sortKeys(value[k])])
    )
  }
  return value
}

const appKey = process.env.OMS_APP_KEY
const appSecret = process.env.OMS_APP_SECRET
const reqTime = String(Math.floor(Date.now() / 1000))
const data = [
  {
    whCode: 'TEST',
    thirdOrderNo: 'SO-20260903-0001',
    subOrderType: 1,
    logisticsChannel: 'T_YAMATO_BIN',
    receiver: '佐藤 健太',
    telephone: '09012345678',
    countryRegionCode: 'JP',
    provinceName: '東京都',
    cityName: '渋谷区',
    postCode: '150-0002',
    addressOne: '渋谷 3-15-7',
    isSubmit: 1,
    itemList: [{ sku: 'APP-TSHIRT-006', quantity: 1 }]
  }
]

const authcode = sign({ appKey, appSecret, data, reqTime })
const res = await fetch(
  `https://api.xlwms.com/openapi/v1/outboundOrder/create?authcode=${authcode}`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ appKey, reqTime, data })
  }
)
console.log(await res.json())
python
# Python 3
import hashlib, hmac, json, os, time, requests

def sort_keys(value):
    if isinstance(value, list):
        return [sort_keys(v) for v in value]
    if isinstance(value, dict):
        return {k: sort_keys(value[k]) for k in sorted(value, key=str.lower)}
    return value

def sign(app_key, app_secret, data, req_time):
    sorted_data = json.dumps(sort_keys(data), ensure_ascii=False, separators=(',', ':'))
    raw = f'{app_key}{sorted_data}{req_time}'
    return hmac.new(app_secret.encode(), raw.encode(), hashlib.sha256).hexdigest()

app_key, app_secret = os.environ['OMS_APP_KEY'], os.environ['OMS_APP_SECRET']
req_time = str(int(time.time()))
data = [{
    'whCode': 'TEST',
    'thirdOrderNo': 'SO-20260903-0001',
    'subOrderType': 1,
    'logisticsChannel': 'T_YAMATO_BIN',
    'receiver': '佐藤 健太',
    'telephone': '09012345678',
    'countryRegionCode': 'JP',
    'provinceName': '東京都',
    'cityName': '渋谷区',
    'postCode': '150-0002',
    'addressOne': '渋谷 3-15-7',
    'isSubmit': 1,
    'itemList': [{'sku': 'APP-TSHIRT-006', 'quantity': 1}],
}]

authcode = sign(app_key, app_secret, data, req_time)
r = requests.post(
    'https://api.xlwms.com/openapi/v1/outboundOrder/create',
    params={'authcode': authcode},
    json={'appKey': app_key, 'reqTime': req_time, 'data': data},
)
print(r.json())

ドロップシッピング出庫受注の作成

POST /v1/outboundOrder/create1 回あたり最大 100 件

主な項目(完全な仕様は公式ドキュメントを参照):

項目必須画面上の項目説明
whCode✳︎倉庫倉庫コード、最大 30
thirdOrderNo✳︎——外部番号。グローバルに一意、最大 100
subOrderType✳︎——1 = 商品単位、2 = 箱単位
logisticsChannel✳︎物流チャンネルチャンネルコード(例:T_YAMATO_BIN
referOrderNo参照番号自社システムの番号
platformOrderNoプラットフォーム受注番号モール側の注文番号
isSubmit——0 = ドラフト保存(既定)、1 = そのまま提出
remark備考API は 255 まで。ただし配送業者側は全角 32 まで
receiver✳︎受取人
telephone電話番号API では任意。ただしヤマト・佐川は必須
countryRegionCode✳︎国・地域日本は JP 固定
provinceName✳︎都道府県日本は都道府県名(例:東京都
provinceCode✳︎都道府県米国・カナダ・オーストラリアでは必須
cityName✳︎都市名日本は市区町村
postCode✳︎郵便番号
addressOne✳︎アドレス1API は 255 まで。ただし配送業者側は全角 16 まで
addressTwoアドレス2同上、全角 16 まで
district市区町村(区/县)日本宛では空欄
itemList[].sku✳︎SKU
itemList[].quantity✳︎出庫数
方法 1 と共通 業務ルールは管理画面での作成とまったく同じです。日本の住所の分け方、電話番号が必須になる配送業者、文字数上限は方法 1 を参照してください。API 側の文字数制限は配送業者より緩く、API では通っても配送業者側で問題になります注意 isSubmit で受注の行き先が決まります。1 なら即提出となり、その後の分岐は配送業者次第です——ヤマトは倉庫処理中へ直行、佐川はドラフトの「提出待ち」で止まります。STEP 6 を参照。

作成後に使う API

用途API
出庫受注の一覧をページング取得getParcelOutboundOrders
出庫受注の詳細取得(ステータス・追跡番号の取得)getOutboundOrder
出庫受注の一括キャンセル(非同期batchCancelOutboundOrder
出庫受注の集約ステータス取得(キャンセル結果の確認)selectBizStatus
追跡番号・送り状の更新(自社送り状を使う場合)updateTrackNoAndLabel
出庫受注へのメッセージ・添付の追加replyBigOutboundMessage

必ず避けたい 3 つの落とし穴

重要 HTTP 500 は作成失敗を意味しません。 公式ドキュメントに、ネットワーク異常時は失敗と断定できないと明記されています。闇雲に再送すると受注が二重に作成されます。詳細取得 APIthirdOrderNo を照会し、作成されていないことを確認してから再送してください。注意 code: 200 はリクエストの成功を示すだけで、各受注が作成できたかは別です。1 件ごとの結果は data[].successdata[].msg を確認してください。注意 thirdOrderNo はグローバルに一意です。冪等キーとして使えば、同じ外部番号での再送で二重作成を防げます。リトライ処理の安全網になります。

品揃え転送(ToB)は別の API

このページはすべてドロップシッピング(小包出庫受注)の話です。品揃え転送出庫(ToB)は別系統で、createBigOutboundOrder(商品単位)と createBoxStockOutboundOrder(箱単位)を使います。照会・キャンセルの API も別です。

仕様は公式ドキュメントが正

このページはドロップシッピング出庫受注を連携する際の主な流れと、つまずきやすい点だけをまとめたものです。項目の完全な仕様・エラーコード・他業務の API は公式ドキュメントをご覧ください:https://apidoc-oms.xlwms.com/

領星OMS操作ドキュメントと併せてご利用ください