midtrans / midtrans-php
Midtrans支付API的PHP包装器。
Requires
- php: >=5.4
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: 5.7.*
- psy/psysh: 0.4.*
This package is auto-updated.
Last update: 2024-09-23 11:31:41 UTC
README
Midtrans ❤️ PHP!
这是Midtrans支付API官方PHP包装器/库,与Composer兼容。访问 https://midtrans.com 了解产品更多信息,并在 http://docs.midtrans.com 查看更多技术细节。从版本2.6开始,此库现在支持Snap-bi。您可以访问此 文档 了解更多关于Snap-bi的信息。
1. 安装
1.a Composer安装
如果您使用Composer,可以通过composer CLI进行安装
composer require midtrans/midtrans-php
或
将此require行添加到您的composer.json
文件中
{ "require": { "midtrans/midtrans-php": "2.*" } }
然后在您的终端上运行composer install
。
注意:如果您使用Laravel框架,在某些情况下,您可能还需要运行
composer dumpautoload
/Midtrans
将随后可用(自动加载)作为您的Laravel项目中的对象。
1.b 手动安装
如果您不使用Composer,您可以克隆或下载此存储库。
然后您应该在您的代码中引入/autoload Midtrans.php
文件。
require_once dirname(__FILE__) . '/pathofproject/Midtrans.php'; // my code goes here
2. 使用方法
2.1 通用设置
// Set your Merchant Server Key \Midtrans\Config::$serverKey = '<your server key>'; // Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction). \Midtrans\Config::$isProduction = false; // Set sanitization on (default) \Midtrans\Config::$isSanitized = true; // Set 3DS transaction for credit card to true \Midtrans\Config::$is3ds = true;
覆盖通知URL
您可以选择在每个交易中更改或添加自定义通知URL。这可以通过在充值请求中添加额外的HTTP头来实现。
// Add new notification url(s) alongside the settings on Midtrans Dashboard Portal (MAP) Config::$appendNotifUrl = "https://example.com/test1,https://example.com/test2"; // Use new notification url(s) disregarding the settings on Midtrans Dashboard Portal (MAP) Config::$overrideNotifUrl = "https://example.com/test1";
注意:当同时使用
appendNotifUrl
和overrideNotifUrl
时,则仅使用overrideNotifUrl
。
这两个头只能接收最多3个URL。
Idempotency-Key
您可以选择在充值交易中添加idempotency key。这可以通过在充值请求中添加额外的HTTP头来实现。这是一个唯一值,它被放在API请求的头中。Midtrans API接受Idempotency-Key头,以安全地处理重试请求,避免执行相同的操作两次。这对于商家因为网络问题或其他意外错误而没有收到响应的情况非常有用。
Config::$paymentIdempotencyKey = "Unique-ID";
2.2 选择产品/方法
我们有3种不同的支付产品可供使用
- Snap - 可定制的支付弹出窗口将出现在您的网站/应用程序上(无重定向)。文档参考
- Snap Redirect - 客户需要被重定向到由Midtrans托管的支付URL。文档参考
- 核心API (VT-Direct) - 基本后端实现,您可以根据喜好自定义嵌入在 您的网站/应用程序 中的前端(无重定向)。 文档参考
选择最适合您独特需求的一个。
2.2.a Snap
您可以在这里看到Snap示例。
获取Snap令牌
$params = array( 'transaction_details' => array( 'order_id' => rand(), 'gross_amount' => 10000, ) ); $snapToken = \Midtrans\Snap::getSnapToken($params);
当客户点击支付按钮时初始化Snap JS
<html> <body> <button id="pay-button">Pay!</button> <pre><div id="result-json">JSON result will appear here after payment:<br></div></pre> <!-- TODO: Remove ".sandbox" from script src URL for production environment. Also input your client key in "data-client-key" --> <script src="https://app.sandbox.midtrans.com/snap/snap.js" data-client-key="<Set your ClientKey here>"></script> <script type="text/javascript"> document.getElementById('pay-button').onclick = function(){ // SnapToken acquired from previous step snap.pay('<?=$snapToken?>', { // Optional onSuccess: function(result){ /* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2); }, // Optional onPending: function(result){ /* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2); }, // Optional onError: function(result){ /* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2); } }); }; </script> </body> </html>
实现通知处理程序
2.2.b Snap重定向
您可以在这里看到一些Snap重定向示例。
获取支付页面的重定向URL
$params = array( 'transaction_details' => array( 'order_id' => rand(), 'gross_amount' => 10000, ) ); try { // Get Snap Payment Page URL $paymentUrl = \Midtrans\Snap::createTransaction($params)->redirect_url; // Redirect to Snap Payment Page header('Location: ' . $paymentUrl); } catch (Exception $e) { echo $e->getMessage(); }
实现通知处理程序
2.2.c 核心API (VT-Direct)
您可以在这里看到一些核心API示例。
设置客户端密钥
MidtransNew3ds.clientKey = "<your client key>";
结算页面
请参考此文件
结算流程
1. 创建交易详情
$transaction_details = array( 'order_id' => time(), 'gross_amount' => 200000 );
2. 创建商品详情、账单地址、发货地址和客户详情(可选)
// Populate items $items = array( array( 'id' => 'item1', 'price' => 100000, 'quantity' => 1, 'name' => 'Adidas f50' ), array( 'id' => 'item2', 'price' => 50000, 'quantity' => 2, 'name' => 'Nike N90' ) ); // Populate customer's billing address $billing_address = array( 'first_name' => "Andri", 'last_name' => "Setiawan", 'address' => "Karet Belakang 15A, Setiabudi.", 'city' => "Jakarta", 'postal_code' => "51161", 'phone' => "081322311801", 'country_code' => 'IDN' ); // Populate customer's shipping address $shipping_address = array( 'first_name' => "John", 'last_name' => "Watson", 'address' => "Bakerstreet 221B.", 'city' => "Jakarta", 'postal_code' => "51162", 'phone' => "081322311801", 'country_code' => 'IDN' ); // Populate customer's info $customer_details = array( 'first_name' => "Andri", 'last_name' => "Setiawan", 'email' => "test@test.com", 'phone' => "081322311801", 'billing_address' => $billing_address, 'shipping_address' => $shipping_address );
3. 从结算页面获取令牌ID
// Token ID from checkout page $token_id = $_POST['token_id'];
4. 创建交易数据
// Transaction data to be sent $transaction_data = array( 'payment_type' => 'credit_card', 'credit_card' => array( 'token_id' => $token_id, 'authentication'=> true, // 'bank' => 'bni', // optional to set acquiring bank // 'save_token_id' => true // optional for one/two clicks feature ), 'transaction_details' => $transaction_details, 'item_details' => $items, 'customer_details' => $customer_details );
5. 收费
$response = \Midtrans\CoreApi::charge($transaction_data);
6. 信用卡3DS认证
信用卡收费结果可能包含用于3DS认证的redirect_url
。3DS认证应在前端处理,请参考API文档
有关信用卡3DS交易的完整示例,请参考
7. 处理交易状态
// Success if($response->transaction_status == 'capture') { echo "<p>Transaksi berhasil.</p>"; echo "<p>Status transaksi untuk order id $response->order_id: " . "$response->transaction_status</p>"; echo "<h3>Detail transaksi:</h3>"; echo "<pre>"; var_dump($response); echo "</pre>"; } // Deny else if($response->transaction_status == 'deny') { echo "<p>Transaksi ditolak.</p>"; echo "<p>Status transaksi untuk order id .$response->order_id: " . "$response->transaction_status</p>"; echo "<h3>Detail transaksi:</h3>"; echo "<pre>"; var_dump($response); echo "</pre>"; } // Challenge else if($response->transaction_status == 'challenge') { echo "<p>Transaksi challenge.</p>"; echo "<p>Status transaksi untuk order id $response->order_id: " . "$response->transaction_status</p>"; echo "<h3>Detail transaksi:</h3>"; echo "<pre>"; var_dump($response); echo "</pre>"; } // Error else { echo "<p>Terjadi kesalahan pada data transaksi yang dikirim.</p>"; echo "<p>Status message: [$response->status_code] " . "$response->status_message</p>"; echo "<pre>"; var_dump($response); echo "</pre>"; }
8. 实现通知处理程序
2.3 处理HTTP通知
创建独立的Web端点(通知URL)以接收HTTP POST通知回调/钩子。每当交易状态发生变化时,都会发送HTTP通知。示例也在此提供。
$notif = new \Midtrans\Notification(); $transaction = $notif->transaction_status; $fraud = $notif->fraud_status; error_log("Order ID $notif->order_id: "."transaction status = $transaction, fraud staus = $fraud"); if ($transaction == 'capture') { if ($fraud == 'challenge') { // TODO Set payment status in merchant's database to 'challenge' } else if ($fraud == 'accept') { // TODO Set payment status in merchant's database to 'success' } } else if ($transaction == 'cancel') { if ($fraud == 'challenge') { // TODO Set payment status in merchant's database to 'failure' } else if ($fraud == 'accept') { // TODO Set payment status in merchant's database to 'failure' } } else if ($transaction == 'deny') { // TODO Set payment status in merchant's database to 'failure' }
2.4 处理交易
获取交易状态
$status = \Midtrans\Transaction::status($orderId); var_dump($status);
批准交易
如果交易欺诈状态 == 挑战,您可以从商家仪表板或API批准交易
$approve = \Midtrans\Transaction::approve($orderId); var_dump($approve);
取消交易
您可以使用fraud_status == CHALLENGE
取消交易,或使用transaction_status == CAPTURE
的信用卡交易(在它成为SETTLEMENT之前)
$cancel = \Midtrans\Transaction::cancel($orderId); var_dump($cancel);
过期交易
您可以使用transaction_status == PENDING
过期交易(在它成为SETTLEMENT或EXPIRE之前)
$cancel = \Midtrans\Transaction::cancel($orderId); var_dump($cancel);
退款交易
退款交易(不是所有支付渠道都允许通过API退款)您可以使用transaction_status == settlement
退款交易
$params = array( 'refund_key' => 'order1-ref1', 'amount' => 10000, 'reason' => 'Item out of stock' ); $refund = \Midtrans\Transaction::refund($orderId, $params); var_dump($refund);
直接退款交易
通过直接退款API退款交易您可以使用transaction_status == settlement
退款交易
$params = array( 'refund_key' => 'order1-ref1', 'amount' => 10000, 'reason' => 'Item out of stock' ); $direct_refund = \Midtrans\Transaction::refundDirect($orderId, $params); var_dump($direct_refund);
3. Snap-BI (*从v2.6.0开始的新功能)
印尼国家支付开放API标准,简称SNAP,是由印度尼西亚银行发布的国家支付开放API标准。要了解更多信息,您可以阅读此文档
3.1 通用设置
//These config value are based on the header stated here https://docs.midtrans.com/reference/getting-started-1 // Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction). \SnapBi\Config::$isProduction = false; // Set your client id. Merchant’s client ID that will be given by Midtrans, will be used as X-CLIENT-KEY on request’s header in B2B Access Token API. \SnapBi\Config::$snapBiClientId = "YOUR CLIENT ID"; // Set your private key here, make sure to add \n on the private key, you can refer to the examples \SnapBi\Config::$snapBiPrivateKey = "YOUR PRIVATE KEY"; // Set your client secret. Merchant’s secret key that will be given by Midtrans, will be used for symmetric signature generation for Transactional API’s header. \SnapBi\Config::$snapBiClientSecret = "YOUR CLIENT SECRET"; // Set your partner id. Merchant’s partner ID that will be given by Midtrans, will be used as X-PARTNER-ID on Transactional API’s header. \SnapBi\Config::$snapBiPartnerId = "YOUR PARTNER ID"; // Set the channel id here. \SnapBi\Config::$snapBiChannelId = "CHANNEL ID"; // Enable logging to see details of the request/response make sure to disable this on production, the default is disabled. SnapBiConfig::$enableLogging = false;
3.2 创建支付
3.2.1 直接借记(Gopay、Dana、Shopeepay)
有关使用直接借记创建支付更详细的信息,请参考文档
date_default_timezone_set('Asia/Jakarta'); $time_stamp = date("c"); $date = new DateTime($time_stamp); $external_id = "uzi-order-testing" . uniqid(); // Add 10 minutes validity time $date->modify('+10 minutes'); // Format the new date $valid_until = $date->format('c'); $merchant_id = "M001234"; //create direct debit request body/ payload //you can change the payment method on the `payOptionDetails` $debitParams = array( "partnerReferenceNo" => $external_id, "chargeToken" => "", "merchantId" => $merchant_id, "urlParam" => array( array( "url" => "https://www.google.com", "type" => "PAY_RETURN", "isDeeplink" => "Y" ) ), "validUpTo" => $valid_until, "payOptionDetails" => array( array( "payMethod" => "DANA", "payOption" => "DANA", "transAmount" => array( "value" => "100.0", "currency" => "IDR" //currently we only support `IDR` ) ) ), "additionalInfo" => array( "customerDetails" => array( "phone" => "081122334455", "firstName" => "Andri", "lastName" => "Litani", "email" => "andri@litani.com", "billingAddress" => array( "firstName" => "Andri", "lastName" => "Litani", "phone" => "081122334455", "address" => "billingAddress", "city" => "billingCity", "postalCode" => "12790", "countryCode" => "CZH" ), "shippingAddress" => array( "firstName" => "Andri", "lastName" => "Litani", "phone" => "081122334455", "address" => "shippingAddress", "city" => "shippingCity", "postalCode" => "12790", "countryCode" => "CZH" ) ), "items" => array( array( "id" => "1", "price" => array( "value" => "100.00", "currency" => "IDR" ), "quantity" => 1, "name" => "Apple", "brand" => "Apple", "category" => "Subscription", "merchantName" => "amazon prime", "url" => "itemUrl" ) ), "metadata" => array() ) ); /** * Basic example * to change the payment method, you can change the value of the request body on the `payOptionDetails` * the `currency` value that we support for now is only `IDR` */ $snapBiResponse = SnapBi::directDebit() ->withBody($debitParams) ->createPayment($external_id);
3.2.2 虚拟账户(银行转账)
有关VA/银行转账的更详细信息,请参考文档
$external_id = "uzi-order-testing" . uniqid(); $customerVaNo = "6280123456"; $merchant_id = "M001234"; $vaParams = array( "partnerServiceId"=> " 70012", "customerNo"=> $customerVaNo, "virtualAccountNo"=> " 70012" . $customerVaNo, "virtualAccountName"=> "Jokul Doe", "virtualAccountEmail"=> "jokul@email.com", "virtualAccountPhone"=> "6281828384858", "trxId"=> $external_id, "totalAmount"=> [ "value"=> "10000.00", "currency"=> "IDR" ], "additionalInfo"=> [ "merchantId"=> $merchant_id, "bank"=> "mandiri", "flags"=> [ "shouldRandomizeVaNumber"=> false ], "mandiri"=> [ "billInfo1"=> "bank_name", "billInfo2"=> "mandiri", "billInfo3"=> "Name:", "billInfo4"=> "Budi Utomo", "billInfo5"=> "Class:", "billInfo6"=> "Computer Science", "billInfo7"=> "ID:", "billInfo8"=> "VT-12345" ], "customerDetails"=> [ "firstName"=> "Jokul", "lastName"=> "Doe", "email"=> "jokul@email.com", "phone"=> "+6281828384858", "billingAddress"=> [ "firstName"=> "Jukul", "lastName"=> "Doe", "address"=> "Kalibata", "city"=> "Jakarta", "postalCode"=> "12190", "phone"=> "+6281828384858", "countryCode"=> "IDN" ], "shippingAddress"=> [ "firstName"=> "Jukul", "lastName"=> "Doe", "address"=> "Kalibata", "city"=> "Jakarta", "postalCode"=> "12190", "phone"=> "+6281828384858", "countryCode"=> "IDN" ] ], "customField"=> [ "1"=> "custom-field-1", "2"=> "custom-field-2", "3"=> "custom-field-3" ], "items"=> [ [ "id"=> "a1", "price"=> [ "value"=> "1000.00", "currency"=> "IDR" ], "quantity"=> 3, "name"=> "Apel", "brand"=> "Fuji Apple", "category"=> "Fruit", "merchantName"=> "Fruit-store" ], [ "id"=> "a2", "price"=> [ "value"=> "1000.00", "currency"=> "IDR" ], "quantity"=> 7, "name"=> "Apel Malang", "brand"=> "Fuji Apple", "category"=> "Fruit", "merchantName"=> "Fruit-store" ] ] ] ); /** * basic implementation to create payment using va */ $snapBiResponse = SnapBi::va() ->withBody($vaParams) ->createPayment($external_id);
3.2.3 Qris
有关Qris的更详细信息,请参阅此文档。
$external_id = "uzi-order-testing" . uniqid(); $merchant_id = "M001234"; $qrisBody = array( "partnerReferenceNo" => $external_id, "amount" => array( "value" => "1500.00", "currency" => "IDR" ), "merchantId" => $merchant_id, "validityPeriod" => "2030-07-03T12:08:56-07:00", "additionalInfo" => array( "acquirer" => "gopay", "items" => array( array( "id" => "8143fc4f-ec05-4c55-92fb-620c212f401e", "price" => array( "value" => "1500.00", "currency" => "IDR" ), "quantity" => 1, "name" => "test item name", "brand" => "test item brand", "category" => "test item category", "merchantName" => "Merchant Operation" ) ), "customerDetails" => array( "email" => "merchant-ops@midtrans.com", "firstName" => "Merchant", "lastName" => "Operation", "phone" => "+6281932358123" ), "countryCode" => "ID", "locale" => "id_ID" ) ); /** * basic implementation to create payment using Qris */ $snapBiResponse = SnapBi::qris() ->withBody($qrisBody) ->createPayment($external_id);
3.4 获取交易状态
有关获取交易状态的详细信息,请参阅此文档。
$merchant_id = "M001234"; $external_id = "uzi-order-testing" . uniqid(); $directDebitStatusByExternalIdBody = array( "originalExternalId" => "uzi-order-testing66ce90ce90ee5", "originalPartnerReferenceNo" => "uzi-order-testing66ce90ce90ee5", "serviceCode" => "54", ); $directDebitStatusByReferenceBody = array( "originalReferenceNo" => "A1202408280618283vcBaAmf7RID", "serviceCode" => "54", ); $vaStatusBody = array( "partnerServiceId" => " 5818", "customerNo" => "628064192914", "virtualAccountNo" => " 5818628064192914", "inquiryRequestId" => "uzi-order-testing66dc4799e4af5", "paymentRequestId" => "uzi-order-testing66dc4799e4af5", "additionalInfo" => array( "merchantId" => $merchant_id ) ); $qrisStatusBody = array( "originalReferenceNo" => "A120240910100828anKJlXgsi6ID", "originalPartnerReferenceNo" => "uzi-order-testing66e01a9b8c6bf", "merchantId" => $merchant_id, "serviceCode" => "54" ); /** * Example code for Direct Debit getStatus using externalId */ $snapBiResponse = SnapBi::directDebit() ->withBody($statusByExternalId) ->getStatus($external_id); /** * Example code for Direct Debit getStatus using referenceNo */ $snapBiResponse = SnapBi::directDebit() ->withBody($statusByReference) ->getStatus($external_id); /** * Example code for VA (Bank Transfer) getStatus */ $snapBiResponse = SnapBi::va() ->withBody($vaStatusBody) ->getStatus($external_id); /** * * Example code for Qris getStatus */ $snapBiResponse = SnapBi::qris() ->withBody($qrisStatusBody) ->getStatus($external_id);
3.5 取消交易
有关取消支付的详细信息,请参阅此文档。
$merchant_id = "M001234"; $external_id = "uzi-order-testing" . uniqid(); $directDebitCancelByReferenceBody = array( "originalReferenceNo" => "A120240902104935GBqSQK0gtQID" ); $directDebitCancelByExternalIdBody = array( "originalExternalId" => "uzi-order-testing66d5983eabc71" ); $vaCancelBody = array( "partnerServiceId" => " 5818", "customerNo" => "628014506680", "virtualAccountNo" => " 5818628014506680", "trxId" => "uzi-order-testing66dc76754bf1c", "additionalInfo" => array( "merchantId" => $merchant_id ) ); $qrisCancelBody = array( "originalReferenceNo" => "A120240910091847fYkCqhCH1XID", "merchantId" => $merchant_id, "reason" => "cancel reason", ); /** * Basic implementation to cancel transaction using referenceNo */ $snapBiResponse = SnapBi::directDebit() ->withBody($directDebitCancelByReferenceBody) ->cancel($external_id); /** * Basic implementation to cancel transaction using externalId */ $snapBiResponse = SnapBi::directDebit() ->withBody($directDebitCancelByExternalIdBody) ->cancel($external_id); /** * Basic implementation of VA (Bank Transfer) to cancel transaction */ $snapBiResponse = SnapBi::va() ->withBody($vaCancelBody) ->cancel($external_id); /** * Basic implementation of Qris to cancel transaction */ $snapBiResponse = SnapBi::qris() ->withBody($qrisCancelBody) ->cancel($external_id);
3.6 退款交易
有关退款支付的详细信息,请参阅此文档。
$merchant_id = "M001234"; $external_id = "uzi-order-testing" . uniqid(); $directDebitRefundByExternalIdBody = array( "originalExternalId" => "uzi-order-testing66cec41c7f905", "partnerRefundNo" => "uzi-order-testing66cec41c7f905" . "refund-0001".rand(), "reason" => "some-reason", "additionalInfo" => array(), "refundAmount" => array( "value" => "100.00", "currency" => "IDR" )); $directDebitRefundByReferenceBody = array( "originalReferenceNo" => "A120240828062651Y0NQMbJkDOID", "reason" => "some-reason", "additionalInfo" => array(), "refundAmount" => array( "value" => "100.00", "currency" => "IDR" )); $qrisRefundBody = array( "merchantId" => $merchant_id, "originalPartnerReferenceNo" => "uzi-order-testing66e01a9b8c6bf", "originalReferenceNo" => "A120240910100828anKJlXgsi6ID", "partnerRefundNo" => "partner-refund-no-". uniqid(), "reason" => "refund reason", "refundAmount" => array( "value" => "1500.00", "currency" => "IDR" ), "additionalInfo" => array( "foo" => "bar" ) ); /** * Example code for refund using externalId */ $snapBiResponse = SnapBi::directDebit() ->withBody($directDebitRefundByExternalIdBody) ->refund($external_id); /** * Example code for refund using reference no */ $snapBiResponse = SnapBi::directDebit() ->withBody($directDebitRefundByReferenceBody) ->refund($external_id); /** * Example code for refund using Qris */ $snapBiResponse = SnapBi::qris() ->withBody($qrisRefundBody) ->refund($external_id);
3.7 添加额外的头部/覆盖头部
您可以通过使用->withAccessTokenHeader
或->withTransactionHeader
方法链来添加或覆盖头部值。有关Snap-Bi所需的头部值,请参阅此文档,并查看每种支付方式的默认头部。
/** * Example code for Direct Debit refund using additional header */ $snapBiResponse = SnapBi::directDebit() ->withAccessTokenHeader([ "debug-id"=> "va debug id", "X-DEVICE-ID"=>"va device id" ]) ->withTransactionHeader([ "debug-id"=> "va debug id", "X-DEVICE-ID"=>"va device id" ]) ->withBody($directDebitRefundByExternalIdBody) ->refund($external_id); /** * Example code for using additional header on creating payment using VA */ $snapBiResponse = SnapBi::va() ->withAccessTokenHeader([ "debug-id"=> "va debug id", "X-DEVICE-ID"=>"va device id" ]) ->withTransactionHeader([ "debug-id"=> "va debug id", "X-DEVICE-ID"=>"va device id" ]) ->withBody($vaParams) ->createPayment($external_id);
3.8 重复使用访问令牌
如果您已保存之前的访问令牌并希望重复使用,您可以通过使用->withAccessToken
来实现。
/** * Example reusing your existing accessToken by using ->withAccessToken */ $snapBiResponse = SnapBi::va() ->withAccessToken("your-access-token") ->withBody($vaParams) ->createPayment($external_id);
3.9 支付通知
要实现Snap-Bi支付通知,您可以参考此文档。
单元测试
集成测试(沙盒真实交易)
请将phpunit.xml
中的服务器密钥和客户端密钥更改为您自己的。
所有测试
vendor/bin/phpunit
特定测试
vendor/bin/phpunit tests/integration/CoreApiIntegrationTest.php
贡献
开发电子商务插件
在开发新插件时,有一些指南必须注意。
-
处理除IDR以外的货币。 Midtrans
v1
和v2
目前只接受印尼盾的支付。作为补充,服务器上有一个验证来检查项目价格是否为整数。尽管您可能想四舍五入价格,但请不要这样做!如果您的系统使用的是除IDR以外的货币,请相应地将它们转换为IDR,然后在四舍五入价格。 -
考虑使用自动净化功能。