kraser/payum-saferpay

Saferpay Payum插件,提供电子商务和企业功能

v0.5.0 2023-03-06 08:06 UTC

This package is auto-updated.

Last update: 2024-09-06 15:15:20 UTC


README

Build Status Scrutinizer Code Quality Code Coverage Total Downloads

简介

此插件实现了Saferpay规范v1.10,包括电子商务和企业许可证的所有功能。Saferpay电子商务许可证仅提供访问支付页面接口。Saferpay企业许可证提供交易接口、定期付款、存储卡片别名等。有关更详细的比较,请参阅许可选项每个接口支持的支付方式

交易接口提供两种选项:iframe(类似于支付页面)和直接提交卡片数据。最后一个选项仅在您符合PCI标准的情况下可用。

以下是支付页面接口的示例:

以下是交易接口的示例:

要求

功能

此插件支持

所有功能均通过测试覆盖。您可以在功能测试中找到有用的示例。

安装

$ 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

使用

捕获示例

确保您已定义类似于此处描述的PaymentToken实体

//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()

使用引用交易方法的定期付款

  1. 使用定期或分期付款选项捕获付款
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();
  1. 通过提供对先前的引用来捕获新的交易
$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);

使用别名进行定期付款

  1. 获取别名:用户必须在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();
  1. 通过提供别名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);

更改负载区域

  1. 创建自定义扩展(如果你使用symfony包的话)
AppBundle\Extension\ConvertPaymentExtension:
    autowire: true
    public: true
    tags:
        - { name: payum.extension, alias: saferpay_locale_extension, factory: saferpay, gateway: saferpay, prepend: false }
  1. 创建服务
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 条件

致谢

许可协议

此插件采用MIT许可协议。有关完整版权信息,请参阅与源代码一起分发的LICENSE文件。