kraser / payum-saferpay
Saferpay Payum插件,提供电子商务和企业功能
v0.5.0
2023-03-06 08:06 UTC
Requires
- php: ^7.3 || ^8.0
- payum/core: ^1.6
Requires (Dev)
- dms/phpunit-arraysubset-asserts: ^0.4.0
- fabpot/goutte: ^4.0
- php-http/guzzle6-adapter: ^2.0
- phpunit/phpunit: ^9.5
README
简介
此插件实现了Saferpay规范v1.10,包括电子商务和企业许可证的所有功能。Saferpay电子商务许可证仅提供访问支付页面接口。Saferpay企业许可证提供交易接口、定期付款、存储卡片别名等。有关更详细的比较,请参阅许可选项和每个接口支持的支付方式。
交易接口提供两种选项:iframe(类似于支付页面)和直接提交卡片数据。最后一个选项仅在您符合PCI标准的情况下可用。
要求
- PHP 7.3+
- Payum
- 可选 PayumBundle 和 Symfony 3 或 4+
功能
此插件支持
- 支付页面接口
- 交易接口
- 定期付款 使用引用交易方法
- 定期付款 使用别名
- 别名支持:添加和删除、捕获交易
- 指定LIABILITY_SHIFT条件(如果无法进行责任转移,则不会接受付款)
- 处理支付页面接口的支付通知
所有功能均通过测试覆盖。您可以在功能测试中找到有用的示例。
安装
$ composer require karser/payum-saferpay
配置
使用PayumBundle(Symfony)
首先在服务定义中注册网关工厂
# config/services.yaml or app/config/services.yml services: app.saferpay.gateway_factory: class: Payum\Core\Bridge\Symfony\Builder\GatewayFactoryBuilder arguments: [Karser\PayumSaferpay\SaferpayGatewayFactory] tags: - { name: payum.gateway_factory_builder, factory: saferpay }
然后配置网关
您可以使用通用测试账户
凭据或在此处创建个人测试账户这里
# config/packages/payum.yaml or app/config/config.yml payum: gateways: saferpay: factory: saferpay # this is test credentials username: 'API_401860_80003225' password: 'C-y*bv8346Ze5-T8' customerId: '401860' terminalId: '17795278' interface: 'TRANSACTION' #optionally, can be defined via details too optionalParameters: #optionally, add some additional interface options, read more below in section "Additional Configuration" styling_css_url: 'https://acme.com/hosted-page-styles.css' sandbox: true
使用Payum
//config.php use Payum\Core\GatewayFactoryInterface; use Payum\Core\PayumBuilder; use Payum\Core\Payum; use Karser\PayumSaferpay\SaferpayGatewayFactory; /** @var Payum $payum */ $payum = (new PayumBuilder()) ->addDefaultStorages() ->addGatewayFactory('saferpay', static function(array $config, GatewayFactoryInterface $coreGatewayFactory) { return new SaferpayGatewayFactory($config, $coreGatewayFactory); }) ->addGateway('saferpay', [ 'factory' => 'saferpay', # this is test credentials 'username' => 'API_401860_80003225', 'password' => 'C-y*bv8346Ze5-T8', 'customerId' => '401860', 'terminalId' => '17795278', 'interface' => 'TRANSACTION', #optionally, can be defined via details too 'sandbox' => true, ]) ->getPayum() ;
配置路由
您可以包括默认Payum Bundle的路由,尽管只有这些路由实际上由此插件需要
#config/routes.yaml payum_capture_do: path: /payment/capture/{payum_token} controller: PayumBundle:Capture:do #notification route is required only if you use payment page interface #payum_notify_do: # path: /payment/notify/{payum_token} # controller: PayumBundle:Notify:do
使用
捕获示例
确保您已定义类似于此处描述的Payment
和Token
实体
//capture.php use App\Entity\Payment; use Payum\Core\Payum; use Payum\Core\Request\Capture; use Karser\PayumSaferpay\Constants; /** @var Payum $payum */ $storage = $payum->getStorage(Payment::class); $payment = $storage->create(); $payment->setNumber(uniqid()); $payment->setCurrencyCode('USD'); $payment->setTotalAmount(123); //$1.23 USD $payment->setDescription('test payment'); // capture using TRANSACTION interface (default) $payment->setDetails(['Interface' => Constants::INTERFACE_TRANSACTION]); // or capture using PAYMENT_PAGE interface $payment->setDetails(['Interface' => Constants::INTERFACE_PAYMENT_PAGE]); $storage->update($payment); $token = $payum->getTokenFactory()->createCaptureToken('saferpay', $payment, 'done.php'); $captureRequest = new Capture($token); $captureRequest->setModel($payment); $reply = $this->gateway->execute($captureRequest, true); //then redirect user to $reply->getUrl();
//done.php use App\Entity\Payment; use Payum\Core\Payum; use Payum\Core\Request\GetHumanStatus; /** @var Payum $payum */ $token = $payum->getHttpRequestVerifier()->verify($_GET); $this->payum->getHttpRequestVerifier()->invalidate($token); $payment = $payum->getStorage(Payment::class)->find($token); $this->assertStatus(GetHumanStatus::STATUS_CAPTURED, $payment); $this->gateway->execute($status = new GetHumanStatus($payment)); //status of the payment is in $status->getValue()
使用引用交易方法的定期付款
- 使用定期或分期付款选项捕获付款
use Karser\PayumSaferpay\Constants; $payment = $storage->create(); $payment->setDetails(['Payment' => ['Recurring' => ['Initial' => true]]]); //or $payment->setDetails(['Payment' => ['Installment' => ['Initial' => true]]]); //then capture the payment $captureRequest = new Capture($token); $captureRequest->setModel($payment); $reply = $this->gateway->execute($captureRequest, true); //then redirect user to $reply->getUrl();
- 通过提供对先前的引用来捕获新的交易
$refTransactionId = $payment->getDetails()['Transaction']['Id']; $payment = $storage->create(); $payment->setDetails([ 'TransactionReference' => [ 'TransactionId' => $refTransactionId, ] ]); //then capture the payment $captureRequest = new Capture($token); $captureRequest->setModel($payment); $this->gateway->execute($captureRequest);
使用别名进行定期付款
- 获取别名:用户必须在iframe中输入他们的卡片详细信息。
use Karser\PayumSaferpay\Constants; use Karser\PayumSaferpay\Model\CardAlias; $cardAliasStorage = $this->payum->getStorage(CardAlias::class); $alias = $cardAliasStorage->create(); $alias->setDetails([ 'Alias' => [ 'IdGenerator' => Constants::ALIAS_ID_GENERATOR_MANUAL, 'Id' => $generatedId = uniqid('id', true), 'Lifetime' => 1600, //days ] ]); $this->cardAliasStorage->update($alias); $token = $this->payum->getTokenFactory()->createCaptureToken(self::GATEWAY_NAME, $cardAlias, 'done.php'); $insertCardAliasRequest = new InsertCardAlias($token); $insertCardAliasRequest->setModel($cardAlias); $reply = $this->gateway->execute($insertCardAliasRequest, true); //then redirect user to $reply->getUrl();
- 通过提供别名ID来捕获新的交易
$aliasId = $cardAlias->getDetails()['Alias']['Id']; $payment = $storage->create(); $payment->setDetails([ 'PaymentMeans' => [ 'Alias' => [ 'Id' => $aliasId, ], ], ]); //then capture the payment $captureRequest = new Capture($token); $captureRequest->setModel($payment); $this->gateway->execute($captureRequest);
更改负载区域
- 创建自定义扩展(如果你使用symfony包的话)
AppBundle\Extension\ConvertPaymentExtension: autowire: true public: true tags: - { name: payum.extension, alias: saferpay_locale_extension, factory: saferpay, gateway: saferpay, prepend: false }
- 创建服务
use Payum\Core\Bridge\Spl\ArrayObject; use Payum\Core\Extension\Context; use Payum\Core\Extension\ExtensionInterface; use Payum\Core\Request\Convert; class ConvertPaymentExtension implements ExtensionInterface { public function onPostExecute(Context $context) { $action = $context->getAction(); $previousActionClassName = get_class($action); if (false === stripos($previousActionClassName, 'ConvertPaymentAction')) { return; } /** @var Convert $request */ $request = $context->getRequest(); if (false === $request instanceof Convert) { return; } // do your locale logic here $customLocale = 'de'; $result = ArrayObject::ensureArrayObject($request->getResult()); $payerData = []; if (isset($result['Payer']) && is_array($result['Payer'])) { $payerData = $result['Payer']; } $payerData['LanguageCode'] = $customLocale; $result['Payer'] = $payerData; $request->setResult((array) $result); } }
其他配置
根据给定的接口,有多个可选选项可用。
示例
payum: gateways: saferpay: optionalParameters: styling_css_url: 'https://acme.com/hosted-page-styles.css'
支付页面接口
交易接口
测试
composer update
vendor/bin/phpunit
待办事项
- 实现独立的操作:授权、取消交易
- 改进并添加更多单元测试
- 配置参数:LIABILITY_SHIFT 条件
致谢
- Dmitrii Poddubnyi dpoddubny@gmail.com
许可协议
此插件采用MIT许可协议。有关完整版权信息,请参阅与源代码一起分发的LICENSE文件。