eksik / bluemedia-php-sdk
Blue Media PHP SDK
Requires
- php: >=7.2
- ext-hash: *
- ext-iconv: *
- ext-json: *
- ext-mbstring: *
- ext-simplexml: *
- ext-xmlreader: *
- ext-xmlwriter: *
- jms/serializer: ^1.14|^2.0|^3.0
- php-http/client-common: ^2.4
- php-http/discovery: ^1.14
- psr/http-client-implementation: ^1.0
- psr/http-factory-implementation: ^1.0
- psr/http-message: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- nyholm/psr7: ^1.4
- php-http/mock-client: ^1.4
- phpunit/phpunit: ^8.5
- symfony/http-client: ^5.3
- symfony/var-dumper: ^5.3
- vimeo/psalm: ^4.8
README
注意:在1.0.0版本中,可能使用有限参数集执行支付和ITN。
要求
- PHP版本7.2或更高。
- PHP扩展
- xmlwriter,
- xmlreader,
- iconv,
- mbstring,
- hash
- 实现库
安装
$ composer require eksik/bluemedia-php-sdk nyholm/psr7 symfony/http-client
客户端配置
为了创建通信层,需要创建一个类BlueMedia\Client
的对象,并传入服务id和共享密钥(由BlueMedia提供)。
$client = new BlueMedia\Client('ID SERWISU', 'KLUCZ WSPÓŁDZIELONY');
在创建客户端对象时,可以在服务数据参数中添加使用的加密模式和数据分隔符(如果指定了非默认值)。
$client = new BlueMedia\Client( 'ID SERWISU', 'KLUCZ WSPÓŁDZIELONY', 'sha256', // tryb hashowania, domyślnie sha256, można użyć stałej z BlueMedia\Common\Enum\ClientEnum '|' // separator danych, domyślnie | );
通过paywall进行交易
执行交易的最简单类型是转到BlueMedia服务并带上交易数据。此时,支付处理完全由BlueMedia服务端完成。
要执行交易,需要调用方法getTransactionRedirect
,正确执行该方法将返回一个表单,该表单将执行到BlueMedia服务的跳转
$result = $client->getTransactionRedirect([ 'gatewayUrl' => 'https://pay-accept.bm.pl', // Adres bramki BlueMedia 'transaction' => [ 'orderID' => '123', // Id transakcji, wymagany 'amount' => '1.20', // Kwota transakcji, wymagany 'description' => 'Transakcja 123-123', // Tytuł transakcji, opcjonalny 'gatewayID' => '0', // Identyfikator kanału płatności, opcjonalny, w tym przypadku można ustawić jako 0 lub pominąć 'currency' => 'PLN', // Waluta transakcji, opcjonalny, domyślnie PLN 'customerEmail' => 'test@hostname.domain' // Email klienta, opcjonalny, zalecany ze względu na automatyczne uzupełnienie pola po stronie serwisu BM ] ]); echo $result->getData();
支付完成后,BlueMedia服务将跳转到之前配置的支付返回地址。跳转是通过HTTPS(GET)请求完成的,包含三个参数
- ServiceID - 服务ID
- OrderID - 交易ID
- Hash - 基于ServiceID和OrderID计算的校验和。
支付返回页面需要验证Hash的正确性,这可以通过方法doConfirmationCheck
来完成。需要传入GET请求中发送的数据
$data = [ 'ServiceID' => '123456', 'OrderID' => '123', 'Hash' => 'df5f737f48bcef93361f590b460cc633b28f91710a60415527221f9cb90da52a' ]; $result = $client->doConfirmationCheck($data); // true | false
交易前
方法doTransactionInit
扩展了标准的交易开始模型,以处理特定的需求
- 根据发送的参数生成支付链接
- 对客户进行负担(如果不需要客户进行额外的授权)
- 在客户被跳转到系统之前验证支付链接的正确性 - 调用将导致参数和系统配置的验证
- 缩短支付链接 - 而不是几个或十几个参数,链接被缩短到两个标识符
- 隐藏敏感参数的链接数据 - 交易前在后台进行,而继续交易的链接不包含敏感数据,只包含继续标识符
- 在完整模式下(安全模式)使用SDK
该方法接受的参数与通过paywall进行的交易相同,区别在于发送了不同的头部,这样BlueMedia服务可以以不同的方式处理请求。在响应中,会收到继续交易的链接或表示无法继续以及支付状态的响应。
交易前,支付继续链接
$result = $client->doTransactionInit([ 'gatewayUrl' => 'https://pay-accept.bm.pl', 'transaction' => [ 'orderID' => '123', 'amount' => '1.20', 'description' => 'Transakcja 123-123', 'gatewayID' => '0', 'currency' => 'PLN', 'customerEmail' => 'test@hostname.domain' ] ]); $transactionContinue = $result->getData(); $transactionContinue->getRedirectUrl(); // https://pay-accept.bm.pl/payment/continue/9IA2UISN/718GTV5E $transactionContinue->getStatus(); // PENDING $transactionContinue->getOrderId(); // 123 $transactionContinue->toArray(); // [...] // ...
交易前,无法继续
$result = $client->doTransactionInit([ 'gatewayUrl' => 'https://pay-accept.bm.pl', 'transaction' => [ 'orderID' => '123', 'amount' => '1.20', 'description' => 'Transakcja 123-123', 'gatewayID' => '1500', 'currency' => 'PLN', 'customerEmail' => 'test@hostname.domain', 'customerIP' => '127.0.0.1', 'title' => 'Test', ] ]); $transactionInit = $result->getData(); $transactionInit->getConfirmation(); // NOTCONFIRMED $transactionInit->getReason(); // MULTIPLY_PAID_TRANSACTION $transactionInit->getOrderId(); // 123 $transactionInit->toArray(); // [...] // ...
快速转账
快速转账是客户需要自行将系统提供的转账数据重新输入的一种支付方式。可以通过方法doTransactionBackground
获取转账数据。
根据在交易上下文中选择的支付渠道,该方法将返回转账数据或已准备好的表格。
调用示例(交易数据)
$result = $client->doTransactionBackground([ 'gatewayUrl' => 'https://pay-accept.bm.pl', 'transaction' => [ 'orderID' => '12345', 'amount' => '5.12', 'description' => 'Test transaction 12345', 'gatewayID' => '21', 'currency' => 'PLN', 'customerEmail' => 'test@test.test', 'customerIP' => '127.0.0.1', 'title' => 'Test', 'validityTime' => date('Y-m-d H:i:s', strtotime('now +5 hour')), 'linkValidityTime' => date('Y-m-d H:i:s', strtotime('now +5 hour')) ] ]); $transactionBackground = $result->getData(); $transactionBackground->getReceiverNRB(); // 47 1050 1764 1000 0023 2741 0516 $transactionBackground->getReceiverName(); // Blue Media $transactionBackground->getBankHref(); // https://ssl.bsk.com.pl/bskonl/login.html $transactionBackground->toArray(); // [...] // ...
调用示例(支付表格)
$result = $client->doTransactionBackground([ 'gatewayUrl' => 'https://pay-accept.bm.pl', 'transaction' => [ 'orderID' => '12345', 'amount' => '5.12', 'description' => 'Test transaction 12345', 'gatewayID' => '1500', 'currency' => 'PLN', 'customerEmail' => 'test@test.test', 'customerIP' => '127.0.0.1', 'title' => 'Test', 'validityTime' => date('Y-m-d H:i:s', strtotime('now +5 hour')), 'linkValidityTime' => date('Y-m-d H:i:s', strtotime('now +5 hour')) ] ]); $transactionBackground = $result->getData(); echo $transactionBackground; // <form action="https://pg-accept.blue.pl/gateway/test/index.jsp" name="formGoPBL" method="POST"><input type="hidden" name="transaction" value="758519"> (...)
ITN(即时交易通知)处理
BlueMedia服务在完成支付后,会向预先配置的ITN地址发送关于支付状态的通信。数据以XML格式发送,并附加base64编码。SDK提供了一个doItnIn
方法,当从BlueMedia服务传递数据时,它会返回一个已准备好的BlueMedia\Itn\ValueObject\ItnIn
对象,允许使用访问者或转换为数组。通过此对象,程序员可以使用必要的数据,例如更新数据库中的支付状态等。
处理完ITN通信后,需要传递响应。这可以通过doItnInResponse
方法实现,该方法接受一个ItnIn
对象和一个表示交易确认的参数。
以下为ITN处理的应用示例
$result = $client->doItnIn($_POST['transactions']); $itnIn = $result->getData(); $transactionConfirmed = $client->checkHash($itnIn); // Jeżeli status płatności z ITN jest potwierdzony i hash jest poprawny - zakończ płatność w systemie if ($itnIn->getPaymentStatus() === 'SUCCESS' && $transactionConfirmed) { $order = $this->orderRepository->find($itnIn->getOrderId()); $order->setPaymentCompleted(); } $itnResponse = $client->doItnInResponse($itnIn, $transactionConfirmed); return new Response($itnResponse->getData()->toXml());
ITN处理,创建通信对象
在实现过程中,可能会出现需要基于货币数据配置客户端的情况,例如在处理ITN之前。在这种情况下,程序员可以使用getItnObject
方法来辅助。
$itn = Client::getItnObject($_POST['transactions']); $itn->getCurrency(); // PLN // ...
获取当前可用的法规列表
getRegulationList
方法允许查询当前法规列表,包括在服务中显示和客户接受的链接。
$result = $this->client->getRegulationList('https://pay-accept.bm.pl'); return $result->getData();
获取支付渠道列表
testGetPaywayList
方法允许查询当前的支付列表。
$result = $this->client->getPaywayList('https://pay-accept.bm.pl'); return $result->getData();