Nhảy tới nội dung

Thanh Toán Liên kết Thẻ

Với Thanh Toán Liên Kết Thẻ, chỉ với một cú click chuột, khách hàng đã hoàn tất đơn hàng một cách nhanh chóng và dễ dàng. Mọi giao dịch với thẻ đã liên kết (đã lưu) sau lần thanh toán đầu tiên đều không cần khách hàng nhập lại thông tin thẻ thanh toán.

Luồng Xử Lý

Sơ đồ hoạt động

Token_flow

Diễn giải sơ đồ

Thanh toán lần đầu và lưu thẻ

  • Bước 1: Khách hàng (người dùng) tiến hành thanh toán bằng hình thức thanh toán qua thẻ ATM do MoMo cung cấp.
  • Bước 2: Hệ thống đối tác khởi tạo đơn hàng với thông tin đơn hàng cùng mã đơn hàng (orderid) duy nhất để yêu cầu phương thức thanh toán phù hợp nhất.
  • Bước 3: Sau khi xác thực thông tin đối tác, MoMo trả về URL thanh toán (payUrl).
  • Bước 4: Thanh toán bằng payUrl được trả về khi người dùng thực hiện trên trang của đối tác. Đối tác điều hướng người dùng tới website của MoMo thông qua payUrl lấy được từ bước 3.
  • Bước 5,6: Khách hàng tiến hành nhập thông tin thẻ ATM và thanh toán.
  • Bước 7: MoMo xử lý thanh toán, sau đó trả về kết quả thanh toán giao dịch, đồng thời điều hướng người dùng về lại web/app của đối tác. cbToken (token để gọi lại) được trả về cùng với kết quả liên kết thành công.
  • Bước 8: Đối tác nhận kết quả thanh toán của mã đơn hàng và cbToken từ MoMo thông qua callback/response/ipn, sau đó hiển thị kết quả cho user.
  • Bước 9: Đối tác dùng cbToken nhận được gọi hàm lần nữa để lấy token thanh toán (recurring token) từ MoMo. Token này được sử dụng cho những lần thanh toán sau.
  • Bước 10: MoMo tạo recurring token được mã hóa (aesToken) và trả về cho đối tác.
  • Bước 11: Sau khi nhận, đối tác giải mã aesToken, lấy thông tin token thanh toán để lưu trữ trong hệ thống, và sử dụng token này cho những thanh toán sau.

Thanh toán tiếp theo

  • Bước 12: Khách hàng thêm sản phẩm vào giỏ hàng và lựa chọn thanh toán bằng thẻ.
  • Bước 13: Hệ thống đối tác khởi tạo phiên thanh toán, gửi yêu cầu thanh toán kèm aesToken tới MoMo.
  • Bước 14: MoMo xử lý thanh toán, sử dụng hashToken (token được mã hóa). MoMo thông báo kết quả tới đối tác và điều hướng người dùng về lại trang của đối tác.
  • Bước 15: Đối tác kiểm tra kết quả thanh toán và hiển thị hoặc cập nhật kết quả này trên web/app của mình.

Cấu Hình API

HTTP Information

Phương thức thiết lập liên kết

HTTP Request

POST /v2/gateway/api/create

AttributeTypeRequiredDescription
partnerCodeString(20)Mã đối tác Thông tin tích hợp
requestIdString(50)Định danh duy nhất cho mỗi yêu cầu,
Đối tác sử dụng requestId cho xử lý idempotency
amountString(20)Số tiền cần thanh toán
Nhỏ Nhất: 10.000 VND
Tối đa: 50.000.000 VND
Tiền tệ: VND
Kiểu dữ liệu: Long
orderIdString(50)Mã đơn hàng của đối tác
orderInfoString(200)Thông tin đơn hàng
redirectUrlString(200)Một URL của đối tác. URL này được sử dụng để chuyển trang (redirect) từ MoMo về trang mua hàng của đối tác sau khi khách hàng thanh toán.
Hỗ trợ: AppLink and WebLink
ipnUrlString(200)API của đối tác. Được MoMo sử dụng để gửi kết quả thanh toán theo phương thức IPN (server-to-server)
isSavedCardBooleanĐối tác truyền field thì sẽ không show checkbox lưu thẻ ở user mà sẽ phụ thuộc vào field này để xác định xem có lưu thẻ hay không
partnerClientIdStringĐịnh danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo
extraDataStringGiá trị mặc định là rỗng""
Encode base64 theo định dạng Json: {"key": "value"}
Ví dụ với dữ liệu: {"username": "momo"}thì data extraData: `eyJ1c2VybmFtZSI6ICJtb21vIn0=``
requestTypeString(20)payWithATM
langString(20)Ngôn ngữ của message được trả về (vi hoặc en)
signatureString(65)Chữ ký để xác nhận giao dịch. Sử dụng thuật toán Hmac_SHA256 với data theo định dạng được sort từ a-z :
accessKey=$accessKey&amount=$amount&extraData=$extraData
&ipnUrl=$ipnUrl&orderId=$orderId&orderInfo=$orderInfo
&partnerClientId=$partnerClientId&partnerCode=
$partnerCode&redirectUrl=$redirectUrl&requestId=
$requestId&requestType=$requestType

Mẫu Request

{
"partnerCode": "MOMO_ATM_DEV",
"accessKey": "SvDmj2cOTYZmQQ3H",
"requestId": "1516771499398",
"amount": "0",
"orderId": "1516771499398",
"ipnUrl": "http://localhost:1001",
"redirectUrl": "http://localhost:8081",
"partnerClientId": "abc@gmail.com",
"requestType": "payWithATM",
"lang": "vi",
"signature": "ca3c203f0c16873e688fada17…ee116b636ff407d6fe39"
}
HTTP Response
AttributeTypeRequiredDescription
partnerCodeStringThông tin tích hợp
requestIdStringGiống với yêu cầu ban đầu
orderIdStringMã đơn hàng của đối tác
payUrlStringURL để chuyển từ trang mua hàng của đối tác sang trang thanh toán của MoMo
resultCodeintResult Code
messageStringMô tả lỗi ngôn ngữ dựa trên lang
responseTimeLongThời gian trả kết quả thanh toán về đối tác
Định dạng:: timestamp
partnerClientIdString(50)Định danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo

Mẫu Response

{
"partnerCode": "MOMO_ATM_DEV",
"requestId": "1616577794003",
"orderId": "1616577794003:0123456778",
"amount": 10000,
"responseTime": 1616577795018,
"message": "Thành công",
"resultCode": 0,
"payUrl": "https://test-payment.momo.vn/gateway/pay?t=TU9NT...NTY3Nzg=",
"partnerClientId": "932024090117"
}

Xử lý kết quả thanh toán

Tìm hiểu thêm về Payment Notification.

Mô tả tham số

Bảng mô tả các tham số được MoMo đính kèm trong trong URL redirectUrl và nội dung body của ipnUrl.

AttributeTypeRequiredDescription
partnerCodeStringThông tin tích hợp
requestIdStringrequestId của đối tác
amountLongSố tiền thanh toán
orderIdStringMã đơn hàng của đối tác
orderTypeStringmomo_wallet
partnerUserIdStringĐịnh danh duy nhất của MoMo cho mỗi tài khoản ví MoMo.
orderInfoStringThông tin đơn hàng
partnerClientIdStringĐịnh danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo
callbackTokenStringToken được sử dụng gọi liên kết để lấy được token thanh toán
transIdLongMã giao dịch của MoMo
resultCodeIntegerTrạng thái của đơn hàng
messageStringMô tả lỗi ngôn ngữ dựa trên lang
payTypeStringnapas
responseTimeLongThời gian phản hồi kết quả theo miliseconds
extraDataStringThông tin thêm
signatureStringChữ ký để xác nhận giao dịch. Sử dụng thuật toán Hmac_SHA256 với data theo định dạng được sort từ a-z :
accessKey=$accessKey&amount=$amount&callbackToken=
$callbackToken&extraData=$extraData&message=$message
&orderId=$orderId&orderInfo=$orderInfo&orderType=
$orderType&partnerClientId=$partnerClientId
&partnerCode=$partnerCode&payType=$payType&requestId=
$requestId&responseTime=$responseTime&resultCode=
$resultCode&transId=$transId

Chữ ký sẽ mã hóa bằng secretKeyaccessKey, vì vậy phải lưu trữ cẩn thận, bảo mật tuyệt đối, không được để lộ ra ngoài.

Example

{
"partnerCode": "123456",
"requestId": "1527246504579",
"orderId": "1527246478428",
"partnerClientId": "MoMoAccountTest",
"lang": "vi",
"signature": "13be80957a5ee32107198920fa26aa85a4ca238a29f46e292e8c33dd9186142a"
}
HTTP Response
AttributeTypeDescription
partnerCodeStringMã đối tác
requestIdStringrequestId của đối tác
orderIdStringMã đơn hàng của đối tác
callbackTokenStringCallback token được khởi tạo bởi MoMo
resultCodeintMã trạng thái giao dịch
messageStringMô tả kết quả giao dịch dựa trên lang
responseTimelongThời gian phản hồi kết quả

Ví dụ

{
"partnerCode": "123456",
"requestId": "1527246504579",
"orderId": "1527246478428",
"callbackToken ": "u7YYQZnAbLQivB0p5SHT9LIhjshqarXyobE_WzCCa4vDt58r",
"resultCode": 0,
"message": "Success",
"responseTime": 127264428
}

Lấy token thanh toán (recurring token)

Sau khi nhận callbackToken từ kết quả giao dịch, bên đối tác sẽ gởi yêu cầu đến MoMo để lấy thông tin token của user.

HTTP Request

POST /v2/gateway/api/tokenization/bind

ParameterTypeRequiredDescription
partnerCodeStringThông tin tích hợp
callbackTokenStringcallbackToken token được sử dụng gọi bind để lấy được token thanh toán
requestIdStringĐịnh danh duy nhất cho mỗi yêu cầu,
Đối tác sử dụng requestId cho xử lý idempotency
orderIdStringPhải trùng với orderId gọi payWithATM
partnerClientIdStringPhải trùng với partnerClientId gọi payWithATM
langStringNgôn ngữ của message được trả về (vi hoặc en)
signatureStringChữ ký để xác nhận giao dịch. Sử dụng thuật toán Hmac_SHA256 với data theo định dạng được sort từ a-z :
accessKey=$accessKey&callbackToken=$callbackToken&orderId=
$orderId&partnerClientId=$partnerClientId&partnerCode=
$partnerCode&requestId=$requestId

Mẫu Request

{
"partnerCode": "MOMO_ATM_DEV",
"requestId": "03dc5a00-b37c-11e9-b3a3-2f10f50d933d",
"accessToken": "v2/qml0PbOlrBYjFlZv…8StiawfZPiKoUGvywNHV",
"orderId": "03dc32f0-b37c-11e9-b3a3-2f10f50d933d",
"partnerClientId": "user@momo.vn",
"signature": "fa8b66df31cc7045783323f1e4492d7b71c1de4c9e1b71002f95a1aa869e885a",
"lang": "vi"
}
HTTP Response
AttributeTypeRequiredDescription
partnerCodeStringThông tin tích hợp
requestIdStringrequestId của đối tác
orderIdStringMã đơn hàng của đối tác
aesTokenStringtoken object json encrypted using AES
resultCodeIntegerTrạng thái của đơn hàng
partnerClientIdString Định danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo
responseTimeLongThời gian trả kết quả thanh toán về đối tác
Định dạng:: timestamp
messageStringMô tả lỗi, ngôn ngữ dựa trên lang

Dữ liệu token sau khi được giải mã

AttributeTypeRequiredDescription
valueStringdùng để thanh toán bằng token
cardNumberStringSố thẻ (chỉ hiển thị 4 số thẻ cuối)
bankCodeStringBankCode
cardTypeStringnapas
bankLogoUrlStringUrl chứa logo của bank

Example response

{
"timestamp": 1600678154664,
"partnerCode": "MOMO_ATM_DEV",
"requestId": "03dc5a00-b37c-11e9-b3a3-2f10f50d933d",
"orderId": "03dc32f0-b37c-11e9-b3a3-2f10f50d933d",
"partnerClientId": "user@momo.vn",
"resultCode": 0,
"responseTime": 145784525,
"message": "Success",
"aesToken": "NplHKEhGuFoo5o5vbMeJwrsk7wXEPnCjSZv6DgivW1a8JKw1gdXq2WS7UsPwoJv0yf6rbGiVV6nOKAxU8kTNg4SZraqJnf7GAq9OSE2LiNs="
}

Sau khi nhận aesToken từ MoMo, Server đối tác phải giải mã aesToken để lấy giá trị ban đầu của token và lưu trữ nó trong hệ thống bên phía đối tác. Việc giải mã token thanh toán bằng thuật toán AES cần secrect key có thể tìm thấy ở https://business.momo.vn

Ví dụ

private static String decrypt_AES(String sercretKey, String encryptData) {
try {
IvParameterSpec iv = new IvParameterSpec(new byte[16]);
SecretKeySpec skeySpec = new SecretKeySpec(sercretKey.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encryptData));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return "";
}

Thanh toán bằng Token

Đối tác có thể dùng token đã lấy trước đó để thực hiện thanh toán.

HTTP Request

POST /v2/gateway/api/tokenization/pay

ParameterTypeRequiredDescription
partnerCodeStringThông tin tích hợp
partnerNameStringTên đối tác
storeIdStringMã cửa hàng
orderIdStringMã đơn hàng của đối tác
amountLongSố tiền cần thanh toán
Nhỏ Nhất: 10.000 VND
Tối đa: 50.000.000 VND
Tiền tệ: VND
Kiểu dữ liệu: Long
requestIdString(50)Định danh duy nhất cho mỗi yêu cầu,
Đối tác sử dụng requestId cho xử lý idempotency
tokenStringToken Json object đã được mã hóa bằng RSA sử dụng public Key RSA Encryption
partnerClientIdStringĐịnh danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo
orderInfoStringMô tả chi tiết
redirectUrlStringMột URL của đối tác. URL này được sử dụng để chuyển trang (redirect) từ MoMo về trang mua hàng của đối tác sau khi khách hàng thanh toán.
Hỗ trợ: AppLink and WebLink
ipnUrlStringAPI của đối tác. Được MoMo sử dụng để gửi kết quả thanh toán theo phương thức IPN (server-to-server)
extraDataStringGiá trị mặc định là rỗng""
Encode base64 theo định dạng Json: {"key": "value"}
Ví dụ với dữ liệu: {"username": "momo"}thì data extraData: `eyJ1c2VybmFtZSI6ICJtb21vIn0=``
langStringNgôn ngữ của message được trả về (vi hoặc en)
signatureStringChữ ký để xác nhận giao dịch. Sử dụng thuật toán Hmac_SHA256 với data theo định dạng được sort từ a-z :
accessKey=$accessKey&amount=$amount&extraData=$extraData
&orderId=$orderId&orderInfo=$orderInfo&partnerClientId=
$partnerClientId&partnerCode=$partnerCode&requestId=
$requestId&token=$token

Dữ liệu của token trước khi được mã hõa

AttributeTypeRequiredDescription
valueStringgiá trị của token
requireSecurityCodeBooleanNếu giá trị là false khi tham số security code không được dùng, thanh toán sẽ được gửi trực tiếp đến bên cung cấp thay vì điều hướng đến trang chứa form để điền security code

Example request

{
"token": "sa5s4a54s5a4s5a4s5",
"partnerCode": "MOMO_ATM_DEV",
"partnerName": "Test",
"storeId": "MoMo test store",
"ipnUrl": "abc.com",
"redirectUrl": "abc.com",
"orderId": "12545465654656",
"amount": "20000",
"lang": "vi",
"autoCapture": true,
"orderInfo": "Thanh toan MoMo",
"requestId": "365656d56sd",
"extraData": "",
"partnerClientId": "test@momo.vn",
"signature": "2512s1d2s1ds21d2s1d1ce5d1a251#@"
}

HTTP Response

Với resultCode 8000, cung cấp payUrl ở kết quả trả về. PayUrl này sẽ dùng để điều hướng khách hàng đến trang thanh toán.

AttributeTypeRequiredDescription
partnerCodeStringThông tin tích hợp
orderIdStringMã đơn hàng của đối tác
requestIdStringrequestId của đối tác
amountLongSố tiền thanh toán
transIdLongMã giao dịch của MoMo
responseTimeLongThời gian trả kết quả thanh toán về đối tác
Định dạng:: timestamp
partnerClientIdStringĐịnh danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo
resultCodeIntegerTrạng thái của đơn hàng
messageStringMô tả lỗi, ngôn ngữ dựa trên lang
payUrlStringURL để chuyển từ trang mua hàng của đối tác sang trang thanh toán của MoMo

Mẫu Response

{
"partnerCode": "MOMO_ATM_DEV",
"requestId": "1599645548172",
"orderId": "1599645548172:0123456778",
"amount": 50000,
"responseTime": 145758545,
"partnerClientId": "user@momo.vn",
"resultCode": 0,
"message": "Success"
}

Xóa token

Đối tác có thể yêu cầu xóa token.

HTTP Request

POST /v2/gateway/api/tokenization/delete

ParameterTypeRequiredDescription
partnerCodeStringThông tin tích hợp
requestIdString(50)Định danh duy nhất cho mỗi yêu cầu,
Đối tác sử dụng requestId cho xử lý idempotency
orderIdStringMã đơn hàng của đối tác
storeIdStringMã cửa hàng
tokenStringToken Json object đã được mã hóa bằng RSA sử dụng public Key RSA Encryption
partnerClientIdStringĐịnh danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo
langStringNgôn ngữ của message được trả về (vi hoặc en)
signatureStringChữ ký để xác nhận giao dịch. Sử dụng thuật toán Hmac_SHA256 với data theo định dạng được sort từ a-z :
accessKey=$accessKey&orderId=$orderId&partnerClientId=
$partnerClientId&partnerCode=$partnerCode&requestId=
$requestId&token=$token
HTTP Response
AttributeTypeRequiredDescription
partnerCodeStringThông tin tích hợp
requestIdStringrequestId của đối tác
messageStringMô tả lỗi, ngôn ngữ dựa trên lang
resultCodeIntegerTrạng thái của đơn hàng
partnerClientIdString Định danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo
responseTimeLongThời gian trả kết quả thanh toán về đối tác
Định dạng:: timestamp

Mẫu Response

{
"partnerCode": "MOMO_ATM_DEV",
"orderId": "1600838954650:0123456778",
"requestId": "1600838954650",
"resultCode": 0,
"message": "Success",
"partnerClientId": "test@momo.vn",
"responseTime": 14548754653232
}

Hủy liên kết

  • Request header: application/json
  • Response header: application/json

MoMo cho phép xóa thẻ từ UI nhà MoMo.

Đối tác phải cung cấp endpoint để nhận thông báo về liên kết được hủy từ MoMo, sử dụng HTTP POST.

HTTP Request
AttributeTypeRequiredDescription
partnerCodeStringMã đối tác
requestIdStringĐịnh danh duy nhất cho mỗi yêu cầu,
Đối tác sử dụng requestId cho xử lý
orderIdStringMã đơn hàng đã gọi payWithATM
partnerClientIdStringĐịnh danh của mỗi user (e.g.: user ID hoặc email).
Id này sẽ được dùng để liên kết với user của MoMo
tokenTypeStringatm
requestTypeStringremove
signatureStringChữ ký để xác nhận giao dịch. Sử dụng thuật toán Hmac_SHA256 với data theo định dạng được sort từ a-z :
accessKey=$accessKey&orderId=$orderId&partnerClientId=$partnerClientId
&partnerCode=$partnerCode&requestId=$requestId
&requestType=$requestType&tokenType=$tokenType

Ví dụ

{
"partnerCode": "MOMOIQA420180417",
"requestId": "0e0ceb2a-ea06-4ca7-b63a-e5c8948a5bfc",
"orderId": "012457855:231454545",
"partnerClientId": "sang@momo.com.vn",
"requestType": "remove",
"tokenType": "atm",
"signature": "bd4df3f3bad6815a9a7be1f1f5c8576f3f97eab25327247425f12a3fb4a78873"
}

Bạn cần phản hồi với HTTP code 204 (No Content)!

Truy vấn callbackToken

Hệ thống đối tác không thể nhận hoặc lưu callbackToken có thể gửi yêu cầu đến MoMo để truy vấn callbackToken.

Request header: application/json - Response header: application/json

HTTP Request

POST /v2/gateway/api/tokenization/cbQuery

AttributeTypeRequiredDescription
partnerCodeStringMã đối tác
requestIdStringrequestId của đối tác
orderIdStringPhải trùng với orderId gọi payWithATM
partnerClientIdStringphải trùng với partnerClientId gọi payWithATM
langStringvi hoặc en
signatureStringChữ ký để xác nhận giao dịch. Sử dụng thuật toán Hmac_SHA256 với data theo định dạng được sort từ a-z :
accessKey=$accessKey&orderId=$orderId
&partnerClientId=$partnerClientId&partnerCode=$partnerCode
&requestId=$requestId

Result Codes & Messages

Các result codes và mô tả tương ứng này được chỉ định riêng cho luồng Thanh toán Liên kết Thẻ của Thanh toán thẻ ATM Nội địa. Ngoài ra, vui lòng tìm kiếm những mã khác trong danh sách result codes tổng hợp ở đây.

Result codeDescriptionFinal StatusRecommended actionsType
0Thành công.Yes
1002Giao dịch bị từ chối do nhà phát hành tài khoản thanh toán.YesSự từ chối xảy ra khi thẻ được dùng để thanh toán hiện không còn khả dụng, hoặc kết nối đến hệ thống của nhà phát hành thẻ bị gián đoạn. Vui lòng tạm thời sử dụng phương thức thanh toán khác.User error
2001Giao dịch thất bại do sai thông tin liên kết.YesToken liên kết không tồn tại hoặc đã bị xóa, vui lòng cập nhật dữ liệu của bạn.Merchant error
2007Giao dịch thất bại do liên kết hiện đang bị tạm khóa.YesToken liên kết hiện đang ở trạng thái không hoạt động, do người dùng đã chủ động tạm khóa liên kết.User error
2012Yêu cầu bị từ chối vì token không khả dụng.YesToken không tồn tại hoặc đã bị xóa. Không thể cập nhật trạng thái token.Merchant error
4010Quá trình xác minh OTP thất bại.YesQuá trình xác minh người dùng thất bại. Vui lòng gửi một yêu cầu xác minh người dùng khác để thử lại.User error
4011OTP chưa được gửi hoặc hết hạn.YesVui lòng yêu cầu gửi một mã OTP khác.User error

Xem thêm