Langkau ke kandungan

Carian popular

Sahkan callback dan checksum

Dikemas kini

Apabila bayaran selesai, Bayarcash memaklumkan server anda melalui callback dan menghantar pelanggan kembali melalui return URL. Setiap callback membawa checksum. Semak checksum itu dengan API Secret Key anda sebelum anda mempercayai data itu. Anda juga boleh menambah checksum pada request anda supaya Bayarcash tahu request itu tidak diubah.

Anda menetapkan kedua-dua URL pada setiap payment intent (callback_url dan return_url). Fungsi kedua-duanya berbeza:

Callback URL Return URL
Siapa yang memanggilnya Server Bayarcash, terus ke server anda Browser pelanggan anda, selepas Bayarcash membuat redirect
Cara ia sampai POST GET dengan field dalam query string (API v3)
Boleh dipercayai untuk status pesanan? Ya, selepas anda menyemak checksum Tidak. Pelanggan boleh menutup tab atau menukar URL
Guna untuk Tandakan pesanan sebagai sudah dibayar atau gagal Paparkan page keputusan kepada pelanggan

Kemas kini pesanan anda daripada callback sahaja. Jika return URL sampai dahulu, paparkan mesej “bayaran sedang disahkan” dan tunggu callback. Anda juga boleh menyemak transaksi itu dengan API.

Setiap callback ada field record_type yang menunjukkan jenis callback itu:

Callback Bila ia dihantar
Pre-transaction Pada awal proses bayaran, sebelum rekod transaksi muktamad.
Transaction Apabila bayaran mencapai status akhir (berjaya, gagal, dibatalkan dan sebagainya).
FPX Direct Debit authorization Apabila pelanggan melengkapkan atau meninggalkan enrolment e-Mandate.
FPX Direct Debit bank approval Apabila bank pelanggan meluluskan atau menolak mandate. Callback ini boleh sampai beberapa hari kemudian.
FPX Direct Debit transaction Untuk setiap collection yang diambil daripada mandate yang aktif.

Field status dalam callback transaksi ialah nombor:

Status Maksud
0 New
1 Pending
2 Unsuccessful
3 Successful
4 Cancelled
5 Abandoned

Callback URL anda mesti membalas HTTP 200 selepas ia menyemak dan menyimpan keputusan. Jika ia membalas dengan status lain, atau tidak membalas, Bayarcash akan menghantar callback itu semula. Jadi, handler anda mesti selamat untuk dijalankan dua kali. Sebelum anda memproses pesanan, semak sama ada anda sudah memproses transaction_id itu.

Callback dihantar sebagai POST. Plugin dan SDK Bayarcash membaca callback sebagai form field ($_POST dalam PHP). Jika framework anda menerima application/json, baca body JSON.

Peraturan yang sama digunakan untuk menandatangani request dan mengesahkan callback. Hanya senarai field yang berbeza bagi setiap panggilan. Untuk membina checksum:

  1. Ambil field bagi panggilan itu (lihat jadual di bawah), dengan nilai tepat seperti yang dihantar atau diterima. Guna nilai kosong untuk field yang tiada.
  2. Susun field mengikut nama field, A hingga Z.
  3. Gabungkan nilai mengikut susunan itu, dengan | di antara setiap nilai.
  4. Kira HMAC-SHA256 bagi teks itu, dengan API Secret Key anda sebagai key. Hasilnya, dalam hex huruf kecil, ialah checksum.

Untuk callback, bandingkan hasil anda dengan field checksum dalam callback itu. Guna perbandingan constant-time, seperti hash_equals() dalam PHP atau hmac.compare_digest() dalam Python. Jika kedua-duanya berbeza, tolak callback itu.

Checksum pada request adalah pilihan, tetapi kami mengesyorkannya. Setiap callback sentiasa ada checksum, jadi sentiasa sahkan checksum itu.

Setiap panggilan menggunakan senarai field sendiri:

Panggilan Field dalam checksum
Cipta payment intent (request) payment_channel, order_number, amount, payer_name, payer_email
Enrolment FPX Direct Debit (request) order_number, amount, payer_name, payer_email, payer_telephone_number, payer_id_type, payer_id, application_reason, frequency_mode
Callback pre-transaction record_type, exchange_reference_number, order_number
Callback transaction record_type, transaction_id, exchange_reference_number, exchange_transaction_id, order_number, currency, amount, payer_name, payer_email, payer_bank_name, status, status_description, datetime
Return URL transaction_id, exchange_reference_number, exchange_transaction_id, order_number, currency, amount, payer_bank_name, status, status_description
Callback FPX Direct Debit bank approval record_type, approval_date, approval_status, mandate_id, mandate_reference_number, order_number, payer_bank_code_hashed, payer_bank_code, payer_bank_account_no, application_type
Callback FPX Direct Debit transaction record_type, batch_number, mandate_id, mandate_reference_number, transaction_id, datetime, reference_number, amount, status, status_description, cycle

Jadual ini menyenaraikan field sahaja. Susunannya ditentukan oleh langkah 2. Jika payment intent ada lebih daripada satu payment_channel, gabungkan nombor saluran dengan koma (1,5) sebelum anda menambahnya, seperti yang PHP SDK buat. Untuk request maintenance dan callback authorization FPX Direct Debit, guna method pengesahan dalam SDK rasmi. Method itu ada senarai field yang tepat.

Contoh: sahkan callback transaksi dalam PHP

Section titled “Contoh: sahkan callback transaksi dalam PHP”

Kod ini menyemak callback transaksi tanpa SDK. Dengan PHP SDK, verifyTransactionCallbackData() membuat semakan yang sama dalam satu baris.

function bayarcash_checksum(array $data, array $fields, string $secretKey): string
{
$payload = [];
foreach ($fields as $field) {
$payload[$field] = $data[$field] ?? '';
}
ksort($payload);
return hash_hmac('sha256', implode('|', $payload), $secretKey);
}
$fields = [
'record_type', 'transaction_id', 'exchange_reference_number',
'exchange_transaction_id', 'order_number', 'currency', 'amount',
'payer_name', 'payer_email', 'payer_bank_name', 'status',
'status_description', 'datetime',
];
$callback = $_POST;
$expected = bayarcash_checksum($callback, $fields, getenv('BAYARCASH_API_SECRET_KEY'));
if (! hash_equals($expected, (string) ($callback['checksum'] ?? ''))) {
http_response_code(403);
exit;
}
// Checksum is valid: save the result, then answer 200.
http_response_code(200);

Contoh: tandatangani payment intent dalam Python

Section titled “Contoh: tandatangani payment intent dalam Python”

Peraturan yang sama dalam Python, untuk request payment intent:

import hashlib
import hmac
def bayarcash_checksum(values: dict, secret_key: str) -> str:
joined = "|".join(str(values[k]) for k in sorted(values))
return hmac.new(secret_key.encode(), joined.encode(), hashlib.sha256).hexdigest()
checksum = bayarcash_checksum({
"payment_channel": "1",
"order_number": "INV-1001",
"amount": "10.00",
"payer_name": "Ahmad bin Abdullah",
"payer_email": "ahmad@example.com",
}, "YOUR_API_SECRET_KEY")

Hantar hasilnya sebagai checksum bersama field yang lain. Rujukan penuh untuk field ada dalam panduan checksum dalam rujukan API.

  • Guna HTTPS untuk callback URL dan return URL anda. Callback membawa butiran bayaran, dan HTTPS melindungi butiran itu semasa dihantar.
  • Simpan API Secret Key di server anda sahaja. Sesiapa yang ada key ini boleh memalsukan callback yang lulus semakan checksum.
  • Guna pakej framework jika ada untuk framework anda. Pakej Laravel dan Django menambah route callback yang menyemak checksum dan menolak checksum yang salah dengan HTTP 403.

Isu-isu biasa

Kenapa log WooCommerce saya memaparkan "Invalid checksum for order"?

Checksum tidak sepadan. Biasanya API Secret Key salah, atau key itu dari environment yang lain (key sandbox pada callback production, atau sebaliknya). Copy key itu semula dari merchant dashboard yang anda gunakan.

Kenapa checksum saya tidak pernah sepadan walaupun key saya betul?

Guna senarai field yang tepat untuk panggilan itu, susun mengikut nama field, dan guna nilai tepat seperti yang dihantar atau diterima. 10.00 dan 10 menghasilkan checksum yang berbeza. Field yang tiada dikira sebagai nilai kosong. Jangan langkau field itu.

Kenapa callback yang sama sampai dua kali?

Bayarcash menghantar callback semula apabila server anda tidak membalas dengan HTTP 200. Balas dengan 200 selepas anda menyimpan keputusan. Semak juga ID transaksi supaya anda tidak memproses bayaran yang sama dua kali.

Adakah artikel ini membantu?

Cookie settings

We use Google Analytics to see which guides help and where readers get stuck. It is on by default, and you can turn it off. This device keeps your choice.