crypto-pay / binancepay
Binance Pay API for Laravel
Requires
- php: ^7.4|^8.0|^8.1|^8.2
- ext-curl: *
README
Binance Pay API for Laravel
Binance Pay API for PHP and Laravel - 这是一个简单的快速包,用于如何使用官方Binance API发起加密支付。您可以使用它从您的网站发起电子商务支付或任何其他支付。
Binance Pay API
在Binance Pay API中验证请求时,使用API密钥。您可以在Binance商户管理门户中查看和管理您的API密钥。
由于API密钥具有众多权限,因此必须确保其安全。请避免在GitHub、客户端代码等公共可访问位置共享您的秘密API密钥。
必须通过HTTPS进行所有API请求。通过纯HTTP进行的调用将失败。此外,未经身份验证的请求也将失败。
安装
您可以通过composer安装此包
composer require crypto-pay/binancepay
获取API凭证#
Binance使用Binance Pay API密钥来验证API请求。您可以在Binance商户管理门户中查看和管理您的API密钥。
前往:开发者 → 设置 → API密钥 → 生成API密钥
配置
BINANCE_SERVICE_BASE_URL=https://bpay.binanceapi.com BINANCE_SERVICE_RETURN_URL="/binancepay/returnUrl" # The URL to redirect to when the payment is successful. BINANCE_SERVICE_CANCEL_URL="/binancepay/cancelURL" # The URL to redirect to when payment is failed. BINANCE_SERVICE_WEBHOOK_URL="webhook-url" BINANCE_MERCHANT_API_KEY=<api-key> BINANCE_MERCHANT_SECRET_KEY=<secret-key>
基础URL
https://bpay.binanceapi.com
创建订单API#
您可以使用“创建订单”API来发起订单。您将在API响应中收到一个checkoutURL。将用户重定向到checkoutURL,他们可以在我们的Binance托管结账页面上完成支付。
端点
POST /binancepay/openapi/v2/order
请求示例
有关完整的API规范,请访问API请求参考。
{ "env" : { "terminalType": "APP" }, "merchantTradeNo": "9825382937292", "orderAmount": 25.17, "currency": "BUSD", "goods" : { "goodsType": "01", "goodsCategory": "D000", "referenceGoodsId": "7876763A3B", "goodsName": "Ice Cream", "goodsDetail": "Greentea ice cream cone" } }
响应示例
{ "status": "SUCCESS", "code": "000000", "data": { "prepayId": "29383937493038367292", "terminalType": "APP", "expireTime": 121123232223, "qrcodeLink": "https://qrservice.dev.com/en/qr/dplkb005181944f84b84aba2430e1177012b.jpg", "qrContent": "https://qrservice.dev.com/en/qr/dplk12121112b", "checkoutUrl": "https://pay.binance.com/checkout/dplk12121112b", "deeplink": "bnc://app.binance.com/payment/secpay/xxxxxx", "universalUrl": "https://app.binance.com/payment/secpay?_dp=xxx=&linkToken=xxx" }, "errorMessage": "" }
用法
// payment controller use CryptoPay\Binancepay\BinancePay; public function initiateBinancePay(Request $request){ // Other logics $user = Auth::user(); $product = Product::find(100); // Use your own product $data['order_amount'] = 25.17; $data['package_id'] = $product->id; // referenceGoodsId: id from the DB Table that user choose to purchase $data['goods_name'] = $product->name; $data['goods_detail'] = null; $data['buyer'] = [ "referenceBuyerId" => $user->id, "buyerEmail" => $user->email, "buyerName" => [ "firstName" => $user->first_name, "lastName" => $user->last_name ] ]; $data['trx_id'] = $transaction->id; // used to identify the transaction after payment has been processed $data['merchant_trade_no'] = '9825382937292' // Provide an unique code; $transaction = Transaction::create([ 'user_id' => $user->id, 'package_id' => $product->id, 'merchant_trade_no' => $data['merchant_trade_no'], 'currency' => "USDT", 'amount' => $product->amount // others ]); $binancePay = new BinancePay("binancepay/openapi/v2/order"); $res = $binancePay->createOrder($data); if ($result['status'] === 'SUCCESS') { // DO YOUR MAGIC. ITS UPTO YOU 😎 } // FAIL // Other logics }
查询订单#
您可以使用“查询订单”API查询订单并实时检查订单状态。
端点
POST /binancepay/openapi/v2/order/query
请求示例
有关完整的API规范,请访问API请求参考。
{ "merchantTradeNo": "9825382937292" }
响应示例
有关完整的API规范,请访问API请求参考。
{ "status": "SUCCESS", "code": "000000", "data": { "merchantId": "987321472", "prepayId": "29383937493038367292", "transactionId": "23729202729220282", "merchantTradeNo": "9825382937292", "tradeType": "APP", "status": "PAID", "currency": "BUSD", "totalFee": 10.88, "productName": "Ice Cream", "productDetail": "Green Tea ice cream cone", "transactTime": "1425744000123", "createTime": "1425744000000" }, "errorMessage": "" }
您可以使用“状态”参数监控支付状态。
用法
返回 & 取消URL
use CryptoPay\Binancepay\BinancePay; // GET /binancepay/returnUrl public function returnCallback(Request $request) { return $this->checkOrderStatus($request); } // GET /binancepay/cancelURL public function cancelCallback(Request $request) { return $this->checkOrderStatus($request); } private function checkOrderStatus(Request $request): RedirectResponse { $transaction = Transaction::findOr($request->get('trx-id'), function () { // return redirect()->route('preferred-route') // ->with('warning', 'Something went wrong'); // show success invoice }); $order_status = (new BinancePay("binancepay/openapi/v2/order/query")) ->query(['merchantTradeNo' => $transaction->merchant_trade_no]); // Save transaction status or whatever you like according to the order status // $transaction->update(['status' => $order_status['data']['status']]; // dd($order_status); // ITS UPTO YOU 😎 }
Binance Pay: Webhooks#
Binance使用Webhooks在发生某些事情时通知您。我们将立即自动向您发送通知,以保持您对订单状态的最新了解。
您将通过商户管理平台配置webhook端点。
设置Webhooks#
出于安全目的,Binance将为webhook通知添加签名。商家需要使用Binance Pay颁发的公钥验证签名。
工作原理
-
在商户管理平台(MMP)中配置webhook端点。
-
构建有效负载并在您的应用程序中验证签名。请注意,证书端点是固定的。
-
确定您想收到通知的事件。
-
自动接收订单状态通知。
-
接收到通知后,请通过返回HTTP 200和响应体中的“SUCCESS”来确认它。
有关更多详细信息,请阅读官方文档。
回调Webhook端点#
Binance Pay将向合作伙伴发送带有最终状态的订单事件以进行通知。您可以通过Binance商户管理门户配置webhook端点。
如果您在 .env 中设置了 WEBHOOK_ENDPOINT,它将覆盖商家管理门户中的默认 webhook 端点。
BINANCE_SERVICE_WEBHOOK_URL="/binancepay/webhook-url"
订单关闭的结果将通过此 webhook 通知您,bizStatus 的值为 PAY_CLOSED
如果事件发送失败,webhook 将重试最多 6 次以重新发送事件。
验证签名 PHP
构建有效负载
$payload = $headers['Binancepay-Timestamp'] . "\n" . $headers['Binancepay-Nonce'] . "\n" . $entityBody . "\n";
使用 Base64 解码签名
$decodedSignature = base64_decode ( $headers['Binancepay-Signature'] );
使用公钥验证内容#
openssl_verify($payload, $decodedSignature, $publicKey, OPENSSL_ALGO_SHA256 );
查询证书
商家可以使用“查询证书”API 获取公钥和哈希键。
端点
POST /binancepay/openapi/certificates
响应参数
Binance Pay:订单通知
有效负载示例
您可以使用“merchantTradeNo”或“prepayId”来搜索特定订单。请至少输入其中一个。
{ "bizType": "PAY", "data": "{\"merchantTradeNo\":\"9825382937292\",\"totalFee\":0.88000000,\"transactTime\":1619508939664,\"currency\":\"BUSD\",\"openUserId\":\"1211HS10K81f4273ac031\",\"productType\":\"Food\",\"productName\":\"Ice Cream\",\"tradeType\":\"WEB\",\"transactionId\":\"M_R_282737362839373\"}", "bizId": 29383937493038367292, "bizStatus": "PAY_SUCCESS" }
为确保您的服务器已接收并接受通知,请对每个通知返回 HTTP 200 和 SUCCESS 响应。
响应示例
请确保发送适当的响应以指示请求成功。如果您的处理过程成功但未通知 Binance Pay,它将继续发送通知,最多可达六次。但是,如果处理失败,发送 returnCode 为 "FAIL",Binance Pay 将尝试重试操作。
{ "returnCode":"SUCCESS", "returnMessage":null }
24 小时内没有支付活动的订单将自动关闭,请联系 Binance 商家运营(https://merchant.binance.com/en/help)以获取通知。
用法
use CryptoPay\Binancepay\BinancePay; public function callback(Request $request): JsonResponse { $webhookResponse = $request->all(); $publicKey = (new BinancePay("binancepay/openapi/certificates")) ->query($webhookResponse); try { if ($publicKey['status'] === "SUCCESS") { $payload = $request->header('Binancepay-Timestamp') . "\n" . $request->header('Binancepay-Nonce') . "\n" . json_encode($webhookResponse, JSON_THROW_ON_ERROR) . "\n"; $decodedSignature = base64_decode($request->header('Binancepay-Signature')); if (openssl_verify($payload, $decodedSignature, $publicKey['data'][0]['certPublic'], OPENSSL_ALGO_SHA256)) { $merchantTradeNo = json_decode($webhookResponse['data'], true, 512, JSON_THROW_ON_ERROR)['merchantTradeNo']; $transaction = Transaction::where('merchant_trade_no', $merchantTradeNo)->firstOr( function () use ($merchantTradeNo) { throw new \RuntimeException("Order could not be found!: " . $merchantTradeNo); }); switch ($webhookResponse['bizStatus']) { case "PAY_SUCCESS": // $order_status = (new BinancePay("binancepay/openapi/v2/order/query"))->query(compact('merchantTradeNo')); // DO YOUR MAGIC HERE PAYMENT IS SUCCESS 😎 break; case "PAY_CLOSED": // OHH... PAYMENT IS FAILED 🙁 break; } } else { throw new \RuntimeException("Signature verification failed😒🤨"); } } else { throw new \RuntimeException($publicKey["errorMessage"]); } }catch (Exception $e) { return response()->json(['returnCode' => 'FAIL', 'returnMessage' => $e->getMessage()], 200); } return response()->json(['returnCode' => 'SUCCESS', 'returnMessage' => null], 200); }
最后
如果您有任何问题或反馈,请随时通过创建问题来告诉我们。我们重视您的想法和建议,并鼓励您通过提交拉取请求来为项目做出贡献。
即将推出的开发 😶🌫️👹
C2B - 客户到商家
- 创建订单/初始化
- 创建订单重构,具有更多自定义功能(v1.0.0 仅接受 USDT)。
- 查询订单
- 关闭订单
- 退款订单
- 查询退款订单
- 支付付款人验证
- 转账资金:转账资金
- 转账资金:查询转账结果
- 子商户:创建子商户
- 钱包余额:查询钱包余额
- 钱包余额:查询钱包余额 V2
- 直接借记:直接借记/预授权创建合同
- 直接借记:直接借记/预授权查询合同
- 直接借记:直接借记支付通知
- 直接借记:直接借记/预授权支付
- 支付:批量支付
- 支付:验证收款人
- 支付:查询支付
- 转换:列出所有转换对
- 转换:发送报价
- 转换:执行报价
- 转换:获取订单状态
- 报告:下载报告
- 报告:下载余额报告
- 利润分享:添加收款人
- 利润分享:查询收款人
- 利润分享:删除收款人
- 利润分享:提交拆分
- 利润分享:查询拆分
- 共享信息:共享账户 ID
- Webhook 通知:订单通知
- Webhook 通知:支付通知
- Webhook 通知:退款通知
C2C - 客户到客户
- OAuth API:查询支持的货币
- OAuth API:创建收款
- 查询收款结果
- Webhook:收款通知
Binance Pay 官方文档
https://merchant.binance.com/en/docs/home
https://developers.binance.com/docs/binance-pay/introduction
贡献指南
感谢您考虑为我们提供的 Laravel 包做出贡献!我们欢迎所有贡献,并感谢您为使此包变得更好所花费的时间和精力。
报告错误
如果您遇到了包中的错误或问题,请在GitHub仓库中新建一个问题,并清晰地描述问题、复现步骤以及任何相关的错误信息或日志。展示问题的截图或代码片段也可能有所帮助。
修改内容
如果您想修改该包,请将该仓库fork,并为您的修改创建一个新分支。在开始任何工作之前,请检查开放的issue和pull request,以确保没有人已经解决了该问题或做出了类似修改。
一旦您完成修改,请创建一个pull request,并清晰地描述修改内容,包括任何相关的代码片段或截图。如果您的修改与开放的issue相关,请在pull request描述中引用该issue。
代码标准
我们遵循Laravel代码标准和PSR-12编码风格。请确保您的修改符合这些标准。
测试
我们为该包提供了一个测试套件,并要求所有更改都有测试覆盖。请确保您的修改有足够的测试覆盖,并且所有测试都通过。
行为准则
我们有一个行为准则,所有贡献者都需要遵守。在为该包做出贡献之前,请阅读行为准则。
致谢
我们感谢所有贡献,并将对所有贡献者在包文档中给予认可。如果您希望以不同的方式获得认可,请在您的pull request中告知我们。
感谢您的贡献!
贡献
- 💻👨💻👩💻 欢迎提交pull request!我们很高兴看到您的贡献!
- ⭐️ 如果您喜欢我们的工作,请给我们一个star!这对我们意义重大!
- 🔥 Fork并克隆我们的仓库!我们保证,这将是一次美妙的体验!
- 🚀 从我们现有的issue中选择或创建一个新的,并给我们提交一个包含您的bug修复或改进的PR!
- ❤️ 我们总是很高兴看到新的更改和改进
如有任何疑问,请通过邮箱联系: hansajith18@gmail.com