Skip to main content
このページでは、加盟店から最も多く質問される注文作成の項目、文字数制限を含む完全な項目表、 そして最もよくあるエラーの背後にある検証ルールを説明します。

3 つの ID と、それぞれをどこで使うか

実務上のべき等性: 同じ paymentRequestId と同一のパラメーターでリトライすると、重複を作成せず同じ注文が返されます。 同じ paymentRequestId で異なるパラメーターを送ると、A0011 Idempotent param mismatch error で拒否されます。

どの項目が必須で、何文字まで入るかを示す表は 1 つにまとまっていますか?

はい — この表です。ここでの「必須」はすべての注文で必須を意味します。もう 1 つのより大きな項目群は契約上は任意ですが、 特定の決済手段やシナリオでは必須になります。それらは 決済手段ごとの条件付き必須項目 に別途一覧化されており、 参照表は API リファレンス表 にあります。 トップレベル merchantInfo(オブジェクト自体は必須) userInfo(オブジェクト自体は必須) paymentInfo(オブジェクト自体は必須) goodsInfo — オブジェクトは任意です。契約では goodsName と、goodsUrl / appName のいずれかが期待される内容として 文書化されています(コンプライアンスとリスク審査のため)が、作成リクエストが強制するのは以下の文字数制限のみです。 決済手段がそれらを要求するかどうかは、決済手段ごとの条件付きルールです。 cardInfo、riskData、addressInfo、brandInfo — すべて任意のオブジェクト
人を惑わせる非対称性に注意してください:successRedirectUrl と failedRedirectUrl は 1024 文字まで許容しますが、 cancelRedirectUrl は 512 文字のみです。3 つのうち 2 つの項目で通る URL が、3 つ目で失敗することがあります。

値が長すぎる場合、切り詰められますか、それとも拒否されますか?

拒否されます。 文字数制限は注文が作成される前にリクエストに対して適用されます。黙って切り詰められることはなく、 長すぎる値が短縮された形で受理される項目はありません。失敗は A0003 Parameter validation failed として返され、 メッセージに問題の項目名が含まれるため、ペイロードを手で比較するのではなくメッセージを読んでください。 実務上の帰結:呼び出す前にお客様側で文字数を検証してください。特に連結して組み立てる項目 (orderDescription、merchantOrderId、goodsName)と、ユーザーが入力したものすべてについてです。

extendInfo は 128 文字しかありません。もっと渡せますか?また、返ってきますか?

返ってきます。そして、大きくすることはできません。
  • 返ってきます:extendInfo はそのまま保存され、/api/v1/order/inquiry および決済通知でエコーされます — どちらも同じ注文構造を持つため、入れたものはどちらでも変更されずに返ってきます。
  • 128 が上限であり、リクエスト検証の上限なので、129 文字は切り詰めではなく A0003 になります。
したがって、ペイロードではなくキーとして扱ってください:お客様自身の注文参照や短いルーティングトークンを入れ、 残りは自社システムで参照してください。merchantOrderId(64)は業務上の注文番号のために設計された項目であり、 この 2 つがあればあらゆる参照のキーとして十分です。Waffo 側に注文ごとの構造化データが必要なら、意味を持つ項目 — goodsInfo、riskData、addressInfo — がその本来の置き場所であり、extendInfo ではありません。

同じ paymentRequestId を再送すると、正確には何が起きますか?

paymentRequestId のスコープはお客様の加盟店 ID であり、チェックは新しい注文が作成される前に実行されます。 比較されるのは 2 つ — orderAmount と orderCurrency です。 既存の注文が返される場合、受け取る内容はその注文がどこまで進んだかによります。まだ処理中の注文は決済ステップが リトライされ、現在の決済情報を受け取ります。すでに最終状態に到達した注文は保存された結果を再生します — 失敗していた場合は 元の失敗を再生することも含みます。これは意図的なものです:リトライが確定した注文を別の結果に変えることは決してありません。 設計時に考慮すべき 2 つの帰結があります。
  • 比較されるのは金額と通貨だけです。 同じ ID を異なる決済手段、異なるユーザー、異なる説明で再送しても不一致には なりません — 最初の注文が返されます。本当に別の注文が必要なら、新しい paymentRequestId を使ってください。
  • A0040 は「再試行してください」であり、失敗ではありません。 2 つの呼び出しが衝突したことを意味します。 これに対して 2 つ目の注文 ID を作成しないでください。同じ ID で再度呼び出すか、その ID で注文照会を実行してください。

A0040 Order cannot be concurrently created が返されました。リトライすべきですか?

はい — 同じ paymentRequestId で。これは同じ ID に対する 2 つの作成が同時に進行しているときに発生し、 そのうちちょうど 1 つが実際の処理を行い、他方は重複注文からお客様を守るために退けられています。少し待ってリトライするか、 その ID で直接注文照会を実行してください。どちらにしても、存在する 1 つの注文に収束します。 やってはいけないのは、「注文は作成されなかった」と見なして新しい ID で再発行することです。それが本物の二重請求が生まれる経路です。

orderAmount に 0 を送れますか?

ゼロの金額は汎用的な金額チェックでは拒否されません — リクエストレベルのルールは金額が負であってはならない、というものです — しかし、ゼロ金額の注文を実際に作成できるかは使用する決済プロダクトと決済手段によって決まり、ほとんどの決済手段にとって ゼロ金額は意味を持ちません。 したがって、それを前提にフローを構築しないでください。ユースケースが「請求せずにカードを確認する」なら、そのために設計された仕組みは ゼロ金額の注文ではなく トークン化 です。ユースケースが無料の注文なら、Waffo の注文をまったく作成しないでください。 負の金額は A0003 で失敗します。

小数は何桁まで送れますか?金額の形式によって拒否されることはありますか?

小数点以下の桁数は通貨の ISO 4217 の精度に対してチェックされ、桁数が多すぎる値は A0003 で失敗します — 小数を一切持てない通貨や、 異通貨注文の異なる扱いを含む完全なルールは 金額と通貨 と 注文金額、上限、拒否 にあります。 もう 1 つ、目立たないチェックがあります。一部の決済手段と通貨の組み合わせは、ある刻み幅の整数倍の金額のみを受け付けます — たとえば 10 の倍数のみ、または小数のない整数単位のみ — そしてこのルールは通貨単体ではなく組み合わせに紐づいています。 ある通貨で完全に有効な金額が、特定の決済手段で拒否されることがあるのはこのためです。価格が端数のある数字なら、提供予定の 各決済手段を整った金額ではなく現実的な金額でテストし、拒否をバグではなく設定上の事実として扱ってください。

orderRequestedAt はどんな形式が必要ですか?自社の時計を Waffo に合わせる必要はありますか?

形式はミリ秒精度の ISO 8601 で、末尾にリテラルの Z が付きます — 2023-04-03T03:00:00.000Z。これは UTC タイムスタンプです: +08:00 のような数値オフセットは代替として受け付けられず、秒精度のみも受け付けられません。パースできない値は A0003 で失敗し、 エラーメッセージに期待される形式が示されます。 お客様の時計が Waffo の時計と一致している必要はありません — orderRequestedAt はお客様のリクエスト時刻として記録され、 サーバー時刻とずれていても注文は拒否されません。時計と比較されるタイムスタンプは orderExpiredAt です — そしてその比較は寛容です: すでに過去になっている有効期限は作成時に破棄され、注文はその決済手段のデフォルトの有効期限で作成されるため、お客様側の 時計のバグはエラーとして表面化しません。意図したより長く開いたままになる注文として表面化します。A0034 The order expiry time provided by merchant has expired は契約上存在しますが、作成時に過去の orderExpiredAt を送っても表示されることはありません。 両方のタイムスタンプを同じ UTC 形式で送れば、この種の問題は丸ごと消えます。

riskData は何のためのものですか?省略すると不利になりますか?

riskData は、Waffo には見えないがお客様はすでに知っているユーザー情報を運びます:新規ユーザーか(userIsNew)、 初回購入か(userIsFirstPurchase)、個人か法人か(userType)、登録時の IP(userRegistrationIp)、 最後に確認された IP(userLastSeenIp)、そして法的氏名と表示名です。 任意です。いずれも何かに対して検証されることはなく、省略しても注文は失敗しません。その役割は、決済情報だけで判断するしかない取引について、 リスク審査により多くの材料を与えることです — これらの項目が存在する理由です。送る場合のルールは 2 つ:真実の値を送ること、 そして一貫して送ること。一貫性のない履歴データは、履歴データがないより悪いからです。登録 IP を捏造したり、すべてのユーザーを リピーターとしてフラグ付けしたりしないでください。 同じ論理が userInfo.userBrowserIp と userInfo.userAgent にも当てはまります:一般には任意ですが、Waffo のチェックアウトを使わずに 自社でカードを収集し、カード、Apple Pay、Google Pay のデータを API 経由でポストする場合には期待されます — そのフローでは、 これらが実際のブラウザの唯一のシグナルです。addressInfo は決済手段に従います:契約上は任意で、決済手段やシナリオが配送先住所を 要求する場合に必須になります — 条件付き必須項目 を参照してください。

goodsInfo は送る必要がありますか?goodsUrl または appName だけで十分ですか?

オブジェクト自体は任意で、作成リクエストは文字数制限以外に内部の項目を強制しません — goodsName だけの goodsInfo は受理されます。 契約では goodsName に加えて goodsUrl または appName のいずれかが期待される内容として文書化されています。 それがコンプライアンスとリスク審査が見るものだからです:Web の加盟店は商品 URL を送り、アプリ専業の加盟店はパッケージ名 (例:com.example.app123)を送ります。これらは択一であり、両方ではありません。 goodsInfo 内の項目が欠落として拒否される場合、そのルールはオブジェクトではなく決済手段から来ています:一部の決済手段は商品詳細を 要求し、欠落したパスを他の条件付き必須項目と同じ方法で報告します — 条件付き必須項目 を参照してください。 したがって実務的な助言は:オブジェクトを省略するか、完全な形で送るか、のどちらかです。省略しただけで注文がブロックされることはありませんが、 リスク審査から商品のコンテキストが失われます。一部の業種では、それこそが境界線上の取引を承認に導くコンテキストです。

特定のカード BIN に決済を制限できますか?

はい。JSON 文字列である paymentInfo.payMethodProperties を通じて可能です。2 つのキーが関係します。 数字のみで、各プレフィックスは 4〜9 桁の範囲内でなければなりません。それ以外は A0003 です。cardPrefixPurpose は意図的に設定してください: 「このカードはこのプロモーションの対象外です」と伝えられた購入者と、「このカードは利用できません」と伝えられた購入者の反応は大きく異なり、 この 2 つの文言はこの 1 つの値から決まります。 同じプロパティ項目には、他にも少数の決済手段固有のキーが入ります。一部の市場で必要な支払者の税務識別番号などです — 条件付き必須項目 を参照してください。

決済を 3DS に通すかどうかを決められますか?

カード系の決済では、cardInfo.threeDsDecision で判断を表明できます。値はちょうど 2 つです。 それ以外は無効なカードデータとして拒否されます。これに依存する前に理解しておくべき 2 つの制限があります。
  • 顧客が在席している、カード系の決済にのみ適用されます。加盟店主導の取引 — 顧客がセッションにいない状態で保存済みトークンに 対して行う請求 — では、この項目は適用されません。
  • お客様が表明する判断であり、発行会社についての保証ではありません。認証された決済がその後成功するか、認証されていない決済が 銀行に拒否されるかは、発行会社の判断です。
自社ページでカード番号を収集したい場合、それはパラメーターの問題である前にコンプライアンスの問題です:適切なカードデータの資格が必要であり、 代替手段 — Waffo のチェックアウトまたはトークン化フローにカードを処理させること — こそが トークン化 と チェックアウト のインテグレーションが存在する理由です。

顧客が在席していない状態で保存済みカードに請求するにはどうすればよいですか?

paymentInfo.merchantInitiatedMode を送信します。値は 2 つです。 merchantInitiatedMode を送る場合は常に userPaymentAccessToken が必須です。これがないと請求対象の保存済み認証情報がないため、 リクエストは検証に失敗します。モードを送ることで取引は加盟店主導としてマークされ、それが認証方法を変えます — threeDsDecision が適用されなくなる理由です。 トークンがそもそもどう作成されるか、そして顧客在席の初回決済とその後の請求の違いについては トークン化 を参照してください。

payMethodName に複数の値を入れられますか?

はい。payMethodName と payMethodType はどちらもカンマ区切りのリストを受け付け、値は大文字小文字を区別せずに照合されます。 これが、チェックアウトをちょうど 1 つの決済手段ではなくサブセットに絞る方法です — たとえば、1 つのカードブランドのクレジットとデビットの 両方のエントリを渡して、購入者がどちらでも使えるようにします。 よくあるケースについて公開されているパラメーターガイダンスには、正確に従う価値があります:カードを広く受け付けるには payMethodType="CREDITCARD,DEBITCARD" を渡し、payMethodName は空にして、購入者が入力する BIN からカードブランドが決まるようにします。 単一の決済手段に固定するには両方の項目を渡します。購入者にすべてを選ばせるにはどちらも渡しません。お客様のアカウントの正確な値は /api/v1/paymethodconfig/inquiry または Portal の Payin ページから取得してください — 仕様書からコピーしたリストをハードコードしないでください。

merchantInfo.merchantId が API キーと一致しない場合はどうなりますか?

注文処理が始まる前に、A0003 で即座に失敗します:ボディ内の加盟店 ID は、署名に使った API キーが属する加盟店でなければなりません。 同じチェックには、区別しておく価値のある近接した失敗が 3 つあります。 デバッグ時にこの区別は重要です:この軸での A0003 は間違った識別子を送ったことを意味し、A0006 は識別子は正しいがアカウントが 使用できないことを意味します — 後者はコードでは修正できません。複数の加盟店アカウントを運用している場合、API キーはそのうちの 1 つに属することに注意してください。アカウント横断のキーはありません。 認証と署名 を参照してください。

userId は何のためのものですか?

userId(String 64、必須)は、userEmail と userPhone(形式 +CountryCode-Number、例:+62-08990013157)とともに、 支払うユーザーに対するお客様側の識別子です。これらはお客様側でユーザーを識別するものであり、Waffo のアカウント認証情報ではありません。

userTerminal には何を渡すべきですか?

userTerminal はユーザーが実際にどこにいるかを Waffo に伝え、返される決済リンクがその環境で動作するようにします。 すべての決済手段がすべての端末種別をサポートしているわけではありません。この値は、どの決済手段を提示できるかにも影響します。

productName とは何ですか?DIRECT_PAYMENT はいつ使いますか?

productName は決済プロダクトを選択します:ONE_TIME_PAYMENT、MINI_PROGRAM_PAYMENT、または DIRECT_PAYMENT。 ほとんどの加盟店は ONE_TIME_PAYMENT を使います。アカウントで有効なプロダクトは、Waffo 加盟店 Portal の Payin Service で 確認できます — 契約に含まれないプロダクトを渡すと検証に失敗します。

A0003 Parameter validation failed が返されたのはなぜですか?

最も多い原因は項目の文字数と形式の制限です。加盟店がよくつまずくもの:
  • cancelRedirectUrl — 最大長 512。成功・失敗のリダイレクト URL の半分
  • goodsInfo.goodsUrl — 最大長 128。完全な URL である必要があります(コンプライアンスとリスク審査のために期待されます)
  • userPhone — +CountryCode-Number の形式に従う必要があります
  • orderRequestedAt — ミリ秒付きの ISO 8601 で、末尾に Z が必要です
エラーレスポンスには問題の項目名が含まれます。 上記の項目表 と照合してください。 A0003 ではない形式エラーが 1 つあります:アドレスの形になっていない userEmail は B0007 Invalid email format として返されます。 B0007 が表示された場合、修正すべきはメールアドレスの値であり、文字数やタイムスタンプではありません。

userEmail は必須ですが、メールアドレスを収集していません。何を送ればよいですか?

公開されているフォールバック形式 userId@examples.com に、ユーザーの実際の ID を代入した一意の合成アドレスを送ってください。 形式は検証されます — 値はアドレスの形をしていなければならず、そうでなければ作成は B0007 Invalid email format で失敗します — しかし、 一意性は API では強制されません。だからこそ、一意に保つのはお客様の責任です。 やってはいけないことが 2 つあります。どちらも大きなエラーにはならず、お客様に損害を与えるからです。
  • test@… のようなリテラルのプレースホルダーを送らないでください。
  • 1 つのアドレスを複数のユーザーで共有しないでください。 多数の決済に 1 つのアドレスというのは、まさにリスク審査が検知するように 作られたパターンであり、そのコストは作成呼び出しのエラーではなく、正当な取引の拒否として現れます。
実際のアドレスを収集できるようになったら、実際のものを送ってください。過去のトラフィックにフォールバックを遡及適用する必要がある場合、 それはパラメーターの変更ではなく、お客様の承認を必要とするサポートへの依頼です。

userCurrency はいつ送る必要がありますか?

userCurrency は任意で、「userCurrency is required」というエラーはありません。ユーザーが支払う通貨が orderCurrency と異なる場合に、 その通貨を宣言します。 実際に影響するのは、お客様のどの契約がその注文を処理できるかです。異通貨の注文はその通貨ペア用に設定された契約を通じてのみ ルーティングでき、この項目を省略し、かつ同一通貨の契約も一致しない場合、ルーティング先が何も残らず A0018 Payment method in merchant order does not match with current merchant contract を受け取ります — 決済手段の問題のように読めますが、実際には通貨ペアの問題です。これがこのエンドポイントで最も誤読される失敗です。 異通貨注文について公開されているルールは、payMethodType や payMethodName を固定していない場合は payMethodCountry を送ること、です。 userCurrency 自体は任意のままです。お客様の契約がどの通貨をカバーしているか、また注文上の 3 つの通貨がどう関係するかは どの金額・通貨項目を確認すべきか? にあります。

A0018 Payment method does not match が返されたのはなぜですか?

A0018 は、注文内の決済手段が現在の加盟店契約と一致しないことを意味します。利用できる決済手段はアカウントで有効になっているものに よって決まります — 加盟店 Portal を確認するか、契約を調整するためにインテグレーションサポートにお問い合わせください。

決済が失敗しました — ユーザーが別の決済手段でリトライするにはどうすればよいですか?

新しい paymentRequestId で新しい注文を作成します。前の paymentRequestId を payMethod を変えて再利用するのは べき等性の不一致であり、A0011 で失敗します。 カードから切り替える場合の追加ルールが 1 つあります:保存済みカードトークン(userPaymentAccessToken)はカード決済にのみ有効です。 失敗した試行がカード決済で、リトライがカード以外の決済手段(銀行振込やウォレットなど)を指定する場合、カードトークンを引き継がないでください — その組み合わせはルーティングできず、注文作成は「no available channel」エラーで失敗します。

WeChat Pay のどの決済手段と注文通貨を渡すべきですか?

WeChat Pay は単一の設定ではありません。WECHATPAY は 3 つの地域設定として存在し、それぞれ 1 つの注文通貨に紐づいています。 WECHATPAYHK は別の決済手段です。 ユーザーのウォレットが登録されている場所に合う組み合わせを選んでください — 請求した設定でウォレットがカバーされていない場合、 ユーザーは決済を完了できません。これらのうちどれがアカウントで有効かは /api/v1/paymethodconfig/inquiry で確認してください。 各エントリには決済手段の country と currency が含まれます。

エラーコードの分類