swedbank-spp/swedbank-payment-portal

Swedbank Payment Portal API库提供通过在线银行系统访问的接口,通过促进银行数据的交换,从而可以启动和完成电子商务交易。

v0.9.4.1 2022-06-29 10:12 UTC

README

关于

Swedbank 开发并维护此API库,以帮助并加快商家与电商平台的集成。

对商家的好处

通常,Swedbank支付门户集成是通过技术规范(API文档)完成的。开发者需要分析它,准备特定的软件架构和逻辑,以便向Swedbank支付门户发送和接收支付请求消息。通过使用库,开发者可以节省大量开发时间,并重用我们已创建的代码和逻辑。这极大地加快了商家端的集成过程,当然也大幅度降低了集成成本

此库支持Swedbank支付类型

  • 卡片集成类型HPS;
  • 银行链接;
  • PayPal快速结账;

要求

最低PHP版本要求7.1及以上。

安装说明

已安装composer的项目

这是推荐的安装方式。在您的composer.json中添加依赖项

"require": {
    "swedbank-spp/swedbank-payment-portal": "^0.9"
}

然后在命令提示符或shell中运行 "composer update"。

或者,您可以从命令提示符或shell中执行 "composer require swedbank-spp/swedbank-payment-portal"。

未安装composer的项目

  • 首先将composer下载到项目根目录( https://getcomposer.org.cn/composer.phar
  • 运行命令:php composer.phar init
  • 按Enter键直到命令完成(将创建 "composer.json" 文件)
  • 打开 "composer.json" 并将 "require": {} 替换为
"require": {
    "swedbank-spp/swedbank-payment-portal": "^0.9"
 }
  • 运行命令:php composer.phar update(成功后将在项目中创建 "vendor" 文件夹)
  • 在您的项目index.php中请包含php行require_once(__DIR__.'/vendor/autoload.php'); 这样就可以将composer默认的自动加载器注册到您的项目中。
  • 完成。从现在开始,您可以使用Swedbank支付门户库。

集成

凭证

要能够测试Swedbank支付系统,您需要获取开发和生产环境的凭证。仅用于测试的测试凭证就足够了。

银行链接集成

以下是一个说明完整银行链接过程的序列图。您可以看到,对于银行链接集成,您只需要在库中调用三个方法:“initPayment()”,“handlePendingTransaction()”和“checkPendingTransactions()”。

alt tag

通知

通知用于银行向商家告知交易状态。事件通知通过POST请求发送到预先配置的商家事件URL。此URL必须与购买设置请求中指定的成功和失败URL不同。如果商家需要将这些消息发送到多个位置,可以在您的支付网关账户上配置多个事件通知URL。这些事件通知的格式是XML。在将事件通知成功发送到事件URL后,商家应用程序必须通过向支付网关发送OK的回复来确认已收到此类通知。事件通知机制用于在整个交易生命周期中通知商家支付事件状态。对于Banklink购买交易,可能发送以下事件通知:授权、需要调查、已取消。当商家收到上述事件通知时,他们应响应以下XML:OK。如果支付网关未收到确认收到的信息,网关将多次尝试发送通知。使用SPP库时,需要调用BankLinkService.handleNotification($xmlData)方法来处理通知。“handleNotification”将解析XML并更新系统中的适当交易状态。如果交易得到解决,还会调用在“initPayment”中提供的回调。安全提示:通知URL必须为人所知,并且只能从SPP服务器IP地址访问。配置您的服务器拒绝对该URL的所有其他请求。

使用示例

function someControllerAction() {  // this method must be called whenever Notification URL is accessed.
      $xml = file_get_contents("php://input"); // POST raw data
      try {
          $spp->getBankLinkGateway()->handleNotification($xm);
      } catch (\Exception $e) {
          // here log any exceptions if occurs, because if you will not respond
          // with “<Response>OK</Response>” SPP will repeatedly submit notifications.
      }
      echo "<Response>OK</Response>";
}

支付卡(HPS)集成

支付卡HPS集成与Banklink相同。

alt tag

PayPal集成(Express Checkout)

PayPal集成也与HPS和Banklink相同。

alt tag

Cron作业操作

系统应每分钟调用一次“checkPendingTransactions”操作。这将触发处于待处理状态的事务状态检查。每个交易的状态检查操作时间与cron作业调用间隔无关。每个交易将在30分钟间隔内查询一次。这些设置可以在库中更改。一个例外是诺德亚的Banklink支付:用户点击成功URL后,仅在1分钟后进行第一次诺德亚交易状态查询,之后(如有需要)在30分钟后进行后续查询。这些待处理交易检查仅针对Banklink和支付卡HPS待处理交易,因为这些交易在某些情况下不能直接解决(例如,由于网络问题,用户未重定向到成功URL)。

测试

可以通过使用本节中的测试数据来执行测试交易。从支付网关收到的响应将取决于使用的卡号。这些响应是模拟的,目的是允许在处理信用卡和借记卡时测试常见场景。

建议至少测试以下场景

  • 包括3-D Secure认证的授权(不同金额)
  • 未授权
  • 3-D Secure认证失败

每个商家必须确保支付网关与自己的电子商务系统之间的交互符合预期。

以下是一些按预定方式工作的卡号。在集成和测试/调试各种场景时,它们非常有帮助。

请注意——魔法卡仅用于认证,不得用于生产环境。

万事达卡测试数据

麦德龙测试数据

维萨卡测试数据

3-D Secure测试数据

在集成3-D Secure时可以使用任何魔法卡号。响应将首先由您账户上的3-D Secure配置决定,然后由测试卡号的到期月份决定。

为了生成特定响应,请使用以下卡到期月份

所有库都在“SwedbankPaymentPortal”命名空间下。库的主要入口点是“SwedbankPaymentPortal”类。

以下是一个初始化库的简短示例

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;

$options = new ServiceOptions(
    new CommunicationOptions('https://accreditation.datacash.com/Transaction/acq_a'),
    new Authentication( 'login', 'password' )
);

$spp = new SwedbankPaymentPortal($options);

之后,您可以检索所有所需的支付服务。

下一步是通过调用“SwedbankPaymentPortal”对象的其中一个方法来检索所需的支付服务。

示例

$paypal   = $spp->getPayPalGateway();
$banklink = $spp->getBankLinkGateway();
$hps      = $spp->getPaymentCardHostedPagesGateway();

无论您检索哪种服务,所有服务都包含一个名为“initPayment”的方法,这是主要支付初始化点。

更新

为了帮助其他没有依赖容器的项目,我们在库中添加了一些静态方法,这些方法有助于全局库初始化。

SwedbankPaymentPortal::init(ServiceOptions $options); // you must call this once to initialize library
$spp = SwedbankPaymentPortal::getInstance();  // method will return an object of SwedbankPaymentPortal.

如果您系统没有依赖容器,请使用这些方法以简化过程。

成功/失败URL处理

无论您使用哪种支付方式,都需要为每个“initPayment”调用指定成功/失败URL。

成功或失败URL应该是您自定义的页面,其中包含适当的用户消息。Swedbank支付门户会在购买操作成功或失败时将客户重定向到该URL。Swedbank支付门户库使用额外的服务器到服务器验证操作的成功或失败,因此您必须调用库中的一个最终确定支付的方法

$spp->getBankLinkGateway()->handlePendingTransaction($orderId);
 $spp->getPayPalGateway()->handlePendingTransaction($orderId);
 $spp->getPaymentCardHostedPagesGateway()->hpsQuery($orderId);

(请参考上面的序列图以查看每个步骤必须调用哪些库方法)

最终确定将触发您在“initPayment”方法调用中提供的回调。

因此,为了完全完成交易,您必须知道使用了哪种支付方式以及订单ID是什么,并且这些信息必须包含在您的成功/失败URL中。例如:http://yoururl.com/success.html?payment=banklink&orderid={order_id}

警告:进入成功URL并不意味着购买100%完成。请勿在成功URL动作中执行任何订单完成逻辑!该逻辑必须在回调中执行!

回调设置

主要思想是购买过程是完全异步的,您将在未来的某个时间通过回调方法(您在支付初始化期间提供的)获得通知(“initPayment”)。以下是关于回调的简要说明。

回调是一个实现了CallbackInterface的对象。CallbackInterface包含一个方法

public function handleFinishedTransaction(
   TransactionResult $transactionResult,
   TransactionFrame $transactionFrame,
   PaymentCardTransactionData $paymentCardTransactionData = null
);

当事务解决时(成功或失败)将调用它。

$transactionResult可以是以下值之一 TransactionResult::success(), TransactionResult::failure(), TransactionResult::unfinished().

$transactionFrame - 包含确定成功/失败的最后一个请求的请求和响应。

$paymentCardTransactionData - 包含支付卡信息(到期日期、卡号、授权码)。此参数是可选的,并且仅在HPS或HCC支付方式中可用。

由于交易是异步的,因此回调将在未来的某个时间在其他进程中调用,因此回调必须是一个PHP可序列化对象,并且必须实现serialize()和unserialize()方法。

当库调用“handleFinishedTransaction”时,它将反序列化回调到其之前的状态(调用“initPayment”时的时间)。

如果您需要在“handleFinishedTransaction”调用中获取一些附加信息,最好的方法是在回调构造函数中传递这些信息,并实现serialize以持久化该数据。

例如,它可以是一个发票ID、订单ID、用户ID以及其他在交易完成后所需的操作信息。

更新

我们已包含CallbackInterface的默认实现,名为UrlCallback,现在您可以在“initPayment”中使用它(适用于所有支付方式)。

示例

$spp->getBankLinkGateway()->initPayment(
    $purchaseRequest,
    UrlCallback::create(“http://yourdomain.com/some_secret_complete_handler?order_id={$orderId}”)
);

UrlCallback将使用HTTP POST操作调用提供的URL,带有以下POST字段:“status”,以下之一:SUCCESS或FAIL或UNFINISHED。

安全注意事项:此链接应该是秘密的,并且不可从外部访问。为了提高安全性,您需要为CallbackURL添加IP过滤。唯一允许调用此URL的IP地址应该是127.0.0.1

支付卡交易的电子收据

在支付卡交易完成后,“handleFinishedTransaction”方法的第三个参数将被设置。第三个参数将包含PaymentCardTransactionData对象。

“PaymentCardTransactionData”由以下内容组成

  • pan
  • expiryDate
  • 授权码
  • 商户参考号
  • 完成日期

以下信息必须包含在电子收据中,电子收据应在使用支付卡购买后生成。

Banklink支付

以下是一个表格,列出了可用的银行以及您需要在购买请求中指定的serviceType和paymentMethod。

如何启动Banklink支付的示例

$purchaseAmount = 1500; // 15 Eur 00 ct
$merchantReferenceId = "Invoice01234";

$purchaseRequest = (new PurchaseBuilder())
   ->setDescription("SPP demoshop Order $merchantReferenceId")
   ->setAmountValue($purchaseAmount)
   ->setAmountExponent(2)
   ->setAmountCurrencyCode(978)// for EUR
   ->setConsumerEmail("customer@email.com")
   ->setServiceType(ServiceType::swdBank())
   ->setPaymentMethod(PaymentMethod::swedbank())
   ->setSuccessUrl("SPP") // see chapter “Success / Failure URL Handlingfor more info
   ->setFailureUrl("SPP")
   ->setMerchantReference($merchantReferenceId)
   ->setLanguage("lt")
   ->setPageSetId(1)
   ->getPurchaseRequest();

   $response = $spp->getBankLinkGateway()->initPayment(
       $purchaseRequest,
       new Swedbank_Ordering_Handler_PaymentCompletedCallback(
           $merchantReferenceId
       )
   );

使用回调的HPS示例

将sppdemoshop.eu替换为您的店铺地址。

callback.php 这是回调示例。回调函数需要在设置调用和最终过程中可用。

use SwedbankPaymentPortal\BankLink\CommunicationEntity\HPSQueryResponse\HPSQueryResponse;
use SwedbankPaymentPortal\BankLink\CommunicationEntity\NotificationQuery\ServerNotification;
use SwedbankPaymentPortal\CallbackInterface;
use SwedbankPaymentPortal\CC\PaymentCardTransactionData;
use SwedbankPaymentPortal\SharedEntity\Type\TransactionResult;
use SwedbankPaymentPortal\Transaction\TransactionFrame;

class Swedbank_Ordering_Handler_PaymentCompletedCallback implements CallbackInterface
{

   private $merchantReferenceId;

   public function __construct($merchantReferenceId)
   {
       $this->merchantReferenceId = $merchantReferenceId;
   }

   /**
    * Method for handling finished transaction which ended because of the specified response status.
    *
    * @param TransactionResult         $status
    * @param TransactionFrame          $transactionFrame
    * @param PaymentCardTransactionData $creditCardTransactionData
    */
   public function handleFinishedTransaction(TransactionResult $status, 
        TransactionFrame $transactionFrame, 
        PaymentCardTransactionData $creditCardTransactionData = null)
   {
       if ($status == TransactionResult::success()) {
           // success no you can put flag payment done
       } else if ($status == TransactionResult::failure()) {
           // failure. Do some action here
       } else {
           // unfinished payment
       }
   // This is only for debug. You can log into file if needed.
       mail('YourEmail@domain.lt', 
       'DONE', print_r($status, true).print_r($transactionFrame, true).print_r($creditCardTransactionData, true)); 
       
   }

   public function serialize()
   {
       return json_encode(
           [
               'merchantReferenceId' => $this->merchantReferenceId
           ]
       );
   }
                   
   public function unserialize($serialized)
   {
       $data = json_decode($serialized);

       $this->merchantReferenceId = $data->merchantReferenceId;
   }
}

hps.php 这是设置脚本

// in autoloader and library needed for HPS payment
include dirname(__FILE__) . '/../SwedbankPaymentPortal/vendor/autoload.php';

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;
use SwedbankPaymentPortal\SharedEntity\Amount;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\SetupRequest;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\Transaction;
use SwedbankPaymentPortal\CC\Type\ScreeningAction;
use SwedbankPaymentPortal\CC\Type\TransactionChannel;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\Transaction\TxnDetails;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\Transaction\ThreeDSecure;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\Transaction\CardTxn;

include dirname(__FILE__) . '/callback.php';

$auth = new Authentication('*********', '*********'); // VtID and password
// Generating unique merchant reference. To generate merchant reference 
//please use your one logic. This is only example.
$merchantReferenceId = 'ID235r' . strtotime('now');
$purchaseAmount = '4.99'; // Euro and cents needs to be separated by dot.  

$options = new ServiceOptions(
       new CommunicationOptions(
       'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
       // for production/live use this URL: https://mars.transaction.datacash.com/Transaction
       ), $auth
);

SwedbankPaymentPortal::init($options);  // <- library  initiation
$spp = SwedbankPaymentPortal::getInstance();  // <- library usage

$riskAction = new Transaction\Action(
       ScreeningAction::preAuthorization(), new Transaction\MerchantConfiguration(
       TransactionChannel::web(), 'Vilnius' //Merchant location (city)
       ), new Transaction\CustomerDetails(
       new Transaction\BillingDetails(// Customer details
       'Mr', // title
       'Name Surname', // Name and surname
       'Zip0000', // Post code
       'Street address', // address line 1
       '', // address line 2
       'London', // City
       'UK' // Country
       ), new Transaction\PersonalDetails(// Personal details
       'Name', // Required, Card holder name
       'Surname', // Required. Card holder surname
       '+3705555555' // Required. Card holder phone
       ), new Transaction\ShippingDetails(// Shipping details
       'Mr', // title
       'Name', // name
       'Surname', // surname
       'Street address', // address line 1
       '', // address line 2
       'City', // City
       'UK', // Country
       'Zip0000' // Post code
       ), new Transaction\RiskDetails(
       '127.15.21.55', // Required. Card holder IP address
       'test@test.lt' // Required. Card holder email
       )
       )
);

$txnDetails = new TxnDetails(
       $riskAction, $merchantReferenceId, new Amount($purchaseAmount), new ThreeDSecure(
       'Order nr: ' . $merchantReferenceId, 'http://sppdemoshop.eu/', new \DateTime()
       )
);

$hpsTxn = new Transaction\HPSTxn(
       'http://sppdemoshop.eu/test/hps_confirm.php?way=expiry&order_id=' . $merchantReferenceId, // expire url
       'http://sppdemoshop.eu/test/hps_confirm.php?way=confirmed&order_id=' . $merchantReferenceId, // return url
       'http://sppdemoshop.eu/test/hps_confirm.php?way=cancelled&order_id=' . $merchantReferenceId, // error url
       164, // Page set ID
       // Firs field to show in card input form Name and Surname field. 
       //Firs parameter goes as string 'show' or null. Second field is url for back button in card input form.
       new Transaction\DynamicData(null, 'http://sppdemoshop.eu/')
);

$transaction = new Transaction($txnDetails, $hpsTxn, new CardTxn());
$setupRequest = new SetupRequest($auth, $transaction);
$response = $spp->getPaymentCardHostedPagesGateway()->initPayment(
       $setupRequest,
       new Swedbank_Ordering_Handler_PaymentCompletedCallback($merchantReferenceId)
);
$url = $response->getCustomerRedirectUrl(); // Getting redirect url
header('Location: ' . $url); // redirecting card holder to card input form.

hps_confirm.php 这是最终支付过程

namespace SwedbankPaymentPortal;

include dirname(__FILE__).'/../SwedbankPaymentPortal/vendor/autoload.php';

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;

include dirname(__FILE__) . '/callback.php';


$orderId = $_GET['order_id'];
$way  = $_GET['way'];

if ($way == 'confirmed'){
  $auth = new Authentication('*********','***********');
  $options = new ServiceOptions(
      new CommunicationOptions(
        'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
		// for production/live use this URL: https://mars.transaction.datacash.com/Transaction
      ),
   $auth
  );
  SwedbankPaymentPortal::init($options);  // <- library  initiation
  $spp = SwedbankPaymentPortal::getInstance();  // <- library usage

  $rez = $spp->getPaymentCardHostedPagesGateway()->handlePendingTransaction($orderId); 
  // now you can show user "thank you for your payment, but don't put flag 
  //flag need to put inside callback
  
  echo 'Thank you';
} else if ($way == 'expiry'){
	echo 'Session expired';
	// do same logic if seesion expired
} else { // cancelled
	echo 'Payment cancelled';
	// do some action for cancel logic
}

使用UrlCalback的HPS示例

将sppdemoshop.eu替换为您的店铺地址。仅在无法使用上述示例的情况下使用。

hps_url_calback_hps.php

namespace SwedbankPaymentPortal;
// in autoloader and library needed for HPS payment
include dirname(__FILE__).'/SwedbankPaymentPortal/vendor/autoload.php'; 

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;

use SwedbankPaymentPortal\SharedEntity\Amount;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\SetupRequest;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\Transaction;
use SwedbankPaymentPortal\CC\Type\ScreeningAction;
use SwedbankPaymentPortal\CC\Type\TransactionChannel;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\Transaction\TxnDetails;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\Transaction\ThreeDSecure;
use SwedbankPaymentPortal\CC\HPSCommunicationEntity\SetupRequest\Transaction\CardTxn;


$auth = new Authentication('8*****','********'); // VtID and password
// Generating unique merchant reference. To generate merchant reference 
//please use your one logic. This is only example.
$merchantReferenceId = 'ID235r'.strtotime('now'); 
$purchaseAmount = '4.99'; // Euro and cents needs to be separated by dot.  

$options = new ServiceOptions(
   new CommunicationOptions(
       'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
   	// for production/live use this URL: https://mars.transaction.datacash.com/Transaction
   ),
  $auth
);

SwedbankPaymentPortal::init($options);  // <- library  initiation
$spp = SwedbankPaymentPortal::getInstance();  // <- library usage

$riskAction = new Transaction\Action(
   ScreeningAction::preAuthorization(),
   new Transaction\MerchantConfiguration(
       TransactionChannel::web(),
       'Vilnius' //Merchant location (city)
   ),
   new Transaction\CustomerDetails( 
       new Transaction\BillingDetails( // Customer details
           'Mr', // title
           'Name Surname', // Name and surname
           'Zip0000', // Post code
           'Street address', // address line 1
           '', // address line 2
           'London', // City
           'UK' // Country
       ),
       new Transaction\PersonalDetails( // Personal details
           'Name', // Required, Card holder name
           'Surname', // Required. Card holder surname
           '+3705555555' // Required. Card holder phone
       ),

       new Transaction\ShippingDetails( // Shipping details
           'Mr', // title
           'Name', // name
           'Surname', // surname
           'Street address', // address line 1
           '', // address line 2
           'City', // City
           'UK', // Country
           'Zip0000' // Post code
       ),

       new Transaction\RiskDetails( 
           '127.15.21.55', // Required. Card holder IP address
           'test@test.lt' // Required. Card holder email
       )
   )
);

$txnDetails = new TxnDetails(
   $riskAction,
   $merchantReferenceId,
   new Amount($purchaseAmount),
   new ThreeDSecure(
       'Order nr: ' . $merchantReferenceId,
       'http://sppdemoshop.eu/',
       new \DateTime()
   )
);
    
$hpsTxn = new Transaction\HPSTxn(
   'http://sppdemoshop.eu/confirm.php?way=expiry&order_id='.$merchantReferenceId, // expire url
      'http://sppdemoshop.eu/confirm.php?way=confirmed&order_id='.$merchantReferenceId, // return url
      'http://sppdemoshop.eu/confirm.php?way=cancelled&order_id='.$merchantReferenceId, // error url
   164, // Page set ID
   // Firs field to show in card input form Name and Surname field. 
   //Firs parameter goes as string 'show' or null. Second field is url for back button in card input form.
   new Transaction\DynamicData(null, 'http://sppdemoshop.eu/') 
);

$transaction  = new Transaction($txnDetails, $hpsTxn, new CardTxn());
$setupRequest = new SetupRequest($auth, $transaction);
$response = $spp->getPaymentCardHostedPagesGateway()->initPayment(
  $setupRequest,
  // This url card holder won't be redirected. This url will be called by cronjob to finalize transaction.
 UrlCallback::create("http://sppdemoshop.eu/secretprocesor.php?order_id={$merchantReferenceId}") 
);
$url=$response->getCustomerRedirectUrl(); // Getting redirect url
header('Location: '.$url); // redirecting card holder to card input form.
die();

confirm.php

include dirname(__FILE__).'/SwedbankPaymentPortal/vendor/autoload.php';

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;

$orderId = $_GET['order_id'];
$way  = $_GET['way'];

if ($way == 'confirmed'){
$auth = new Authentication('8******','******');
$options = new ServiceOptions(
    new CommunicationOptions(
      'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
  	// for production/live use this URL: https://mars.transaction.datacash.com/Transaction
    ),
 $auth
);
SwedbankPaymentPortal::init($options);  // <- library  initiation
$spp = SwedbankPaymentPortal::getInstance();  // <- library usage

$rez = $spp->getPaymentCardHostedPagesGateway()->handlePendingTransaction($orderId); 
// now you can show user "thank you for your payment, but don't put flag 
//what this payment is done. This is done in secretprocesor.php file

echo 'Thank you';
} else if ($way == 'expiry'){
  // do same logic if seesion expired
} else { // cancelled
  // do some action for cancel logic
}

secretprocesor.php 此文件不会在浏览器中加载。它将由cron作业调用。

$orderId = $_GET['order_id'];

if($_POST['status'] === 'SUCCESS') {
  	//Do action for success. This is final confirmations of success
  	// now you can set flag what payment is success
  } else if($_POST['status'] === 'FAIL') {
  	// Do action if failed
  } else if($_POST['status'] === 'UNFINISHED'){
  	// Do action if unfinished
  } else {
      // log this attempt 
  }
  

银行链接

将sppdemoshop.eu替换为您的店铺地址。

banklink_setup.php

// in autoloader and library needed for banklink payment
include dirname(__FILE__) . '/../SwedbankPaymentPortal/vendor/autoload.php';

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;

use SwedbankPaymentPortal\BankLink\PurchaseBuilder;
use SwedbankPaymentPortal\BankLink\CommunicationEntity\Type\PaymentMethod;
use SwedbankPaymentPortal\BankLink\CommunicationEntity\Type\ServiceType;

include dirname(__FILE__) . '/callback.php';

$auth = new Authentication('*******', '********'); // VtID and password
// Generating unique merchant reference. To generate merchant reference 
//please use your one logic. This is only example.
$merchantReferenceId = 'ID235r' . strtotime('now');

$options = new ServiceOptions(
        new CommunicationOptions(
        'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
        // for production/live use this URL: https://mars.transaction.datacash.com/Transaction
        ), $auth
);

SwedbankPaymentPortal::init($options);  // <- library  initiation
$spp = SwedbankPaymentPortal::getInstance();  // <- library usage


$purchaseAmount = 1500; // 15 Eur 00 ct


$purchaseRequest = (new PurchaseBuilder())
    ->setDescription("SPP demoshop Order $merchantReferenceId")
    ->setAmountValue($purchaseAmount)
    ->setAmountExponent(2)
    ->setAmountCurrencyCode(978)// for EUR
    ->setConsumerEmail("customer@email.com")
    /*
ServiceType::swdBank() - SWEDBANK AB (SWEDEN)
ServiceType::nrdSwd() - NORDEA BANK AB (SWEDEN)
ServiceType::sebSwd() - SKANDINAVISKA ENSKILDA BANKEN AB (SWEDEN)
ServiceType::estBank() - SWEDBANK AS (ESTONIA)
ServiceType::sebEst() - SEB AS Pank (ESTONIA)
ServiceType::nrdEst() - Nordea Bank AB Estonia Branch (ESTONIA)
ServiceType::ltvBank() - SWEDBANK AS (LATVIA)
ServiceType::sebLtv() - SEB AS banka (LATVIA)
ServiceType::litBank() - SWEDBANK AB (LITHUANIA)
ServiceType::sebLit() - SEB AB bankas (LITHUANIA)
ServiceType::nrdLit() - NORDEA BANK AB LITHUANIA BRANCH (LITHUANIA)
*/        
    ->setServiceType(ServiceType::litBank())
/*
PaymentMethod::swedbank() - SWEDBANK AB (SWEDEN)
PaymentMethod::nordea() - NORDEA BANK AB (SWEDEN)
PaymentMethod::svenska() - SVENSKA HANDELSBANKEN AB (SWEDEN)
PaymentMethod::seb() - SKANDINAVISKA ENSKILDA BANKEN AB (SWEDEN)
PaymentMethod::swedbank() - SWEDBANK AS (ESTONIA)
PaymentMethod::seb() - SEB AS Pank (ESTONIA)
PaymentMethod::nordea() - Nordea Bank AB Estonia Branch (ESTONIA)
PaymentMethod::swedbank() - SWEDBANK AS (LATVIA)
PaymentMethod::seb() - SEB AS banka (LATVIA)
PaymentMethod::citadele() - AS CITADELE BANKA (LATVIA)
PaymentMethod::swedbank() - SWEDBANK AB (LITHUANIA)
PaymentMethod::seb() - SEB AB bankas (LITHUANIA)
PaymentMethod::dnb() - AB DNB BANKAS (LITHUANIA)
PaymentMethod::nordea() - NORDEA BANK AB LITHUANIA BRANCH (LITHUANIA)
PaymentMethod::danske() - DANSKE BANK AS LITHUANIA BRANCH (LITHUANIA)
*/
    ->setPaymentMethod(PaymentMethod::swedbank())
    ->setSuccessUrl('http://sppdemoshop.eu/test/banklink_confirm.php?way=confirmed&order_id=' . $merchantReferenceId) // see chapter “Success / Failure URL Handlingfor more info
    ->setFailureUrl('http://sppdemoshop.eu/test/banklink_confirm.php?way=cancelled&order_id=' . $merchantReferenceId)
    ->setMerchantReference($merchantReferenceId)
    ->setLanguage("lt")
    ->setPageSetId(1) // Always 1
    ->getPurchaseRequest();

    $response = $spp->getBankLinkGateway()->initPayment(
        $purchaseRequest,
        new Swedbank_Ordering_Handler_PaymentCompletedCallback(
            $merchantReferenceId
        )
    );

$url = $response->getCustomerRedirectUrl(); // Getting redirect url
header('Location: ' . $url); // redirecting card holder to card input form.

callback.php

use SwedbankPaymentPortal\BankLink\CommunicationEntity\HPSQueryResponse\HPSQueryResponse;
use SwedbankPaymentPortal\BankLink\CommunicationEntity\NotificationQuery\ServerNotification;
use SwedbankPaymentPortal\CallbackInterface;
use SwedbankPaymentPortal\CC\PaymentCardTransactionData;
use SwedbankPaymentPortal\SharedEntity\Type\TransactionResult;
use SwedbankPaymentPortal\Transaction\TransactionFrame;

class Swedbank_Ordering_Handler_PaymentCompletedCallback implements CallbackInterface
{

    private $merchantReferenceId;

    public function __construct($merchantReferenceId)
    {
        $this->merchantReferenceId = $merchantReferenceId;
    }

    /**
     * Method for handling finished transaction which ended because of the specified response status.
     *
     * @param TransactionResult         $status
     * @param TransactionFrame          $transactionFrame
     * @param PaymentCardTransactionData $creditCardTransactionData
     */
    public function handleFinishedTransaction(TransactionResult $status, 
         TransactionFrame $transactionFrame, 
         PaymentCardTransactionData $creditCardTransactionData = null)
    {
        if ($status == TransactionResult::success()) {
            // success no you can put flag payment done
        } else if ($status == TransactionResult::failure()) {
            // failure. Do some action here
        } else {
            // unfinished payment
        }
	// This is only for debug. You can log into file if needed.
        mail('YourEmail@domain.lt', 
	    'DONE', print_r($status, true).print_r($transactionFrame, true).print_r($creditCardTransactionData, true)); 
	    
    }

    public function serialize()
    {
        return json_encode(
            [
                'merchantReferenceId' => $this->merchantReferenceId
            ]
        );
    }
                    
    public function unserialize($serialized)
    {
        $data = json_decode($serialized);

        $this->merchantReferenceId = $data->merchantReferenceId;
    }
}

banklink_confirm.php

namespace SwedbankPaymentPortal;

include dirname(__FILE__).'/../SwedbankPaymentPortal/vendor/autoload.php';

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;

include dirname(__FILE__) . '/callback.php';


$orderId = $_GET['order_id'];
$way  = $_GET['way'];

if ($way == 'confirmed'){
  $auth = new Authentication('******', '*****');
  $options = new ServiceOptions(
      new CommunicationOptions(
        'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
		// for production/live use this URL: https://mars.transaction.datacash.com/Transaction
      ),
   $auth
  );
  SwedbankPaymentPortal::init($options);  // <- library  initiation
  $spp = SwedbankPaymentPortal::getInstance();  // <- library usage

  $rez = $spp->getBankLinkGateway()->handlePendingTransaction($orderId); 
  // now you can show user "thank you for your payment, but don't put flag 
  //flag need to put inside callback
  
  echo 'Thank you';
} else { // cancelled
	echo 'Payment cancelled';
	// do some action for cancel logic
}

Paypal示例

将sppdemoshop.eu替换为您的店铺地址。

paypal_setup.php

// include autoloader and library needed for paypal payment
include dirname(__FILE__) . '/../SwedbankPaymentPortal/vendor/autoload.php';

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;
use SwedbankPaymentPortal\SharedEntity\Amount;

use SwedbankPaymentPortal\PayPal\CommunicationEntity\ShippingAddress;
use SwedbankPaymentPortal\PayPal\CommunicationEntity\SetExpressCheckoutRequest\Transaction;
use SwedbankPaymentPortal\PayPal\CommunicationEntity\SetExpressCheckoutRequest\Transaction\TxnDetails;
use SwedbankPaymentPortal\PayPal\CommunicationEntity\SetExpressCheckoutRequest\SetExpressCheckoutRequest;
use SwedbankPaymentPortal\PayPal\Type\PayPalBool;


include dirname(__FILE__) . '/callback.php';
include dirname(__FILE__) . '/logger.php';

$auth = new Authentication('*******', '*********'); // VtID and password
// Generating unique merchant reference. To generate merchant reference 
//please use your one logic. This is only example.
$merchantReferenceId = 'ID235r' . strtotime('now');
$purchaseAmount = '4.99'; // Euro and cents needs to be separated by dot.  

$options = new ServiceOptions(
        new CommunicationOptions(
        'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
        // for production/live use this URL: https://mars.transaction.datacash.com/Transaction
        ), $auth, new Swedbank_Client_Logger()
);

SwedbankPaymentPortal::init($options);  // <- library  initiation
$spp = SwedbankPaymentPortal::getInstance();  // <- library usage

$payPalTxn = new Transaction\PayPalTxn(
        null,
    'ABCQWH', // Custom
    'PayPal test payment', //Description
    'customer@customer.com', //Email
    $merchantReference, // Invoice number
    'LT', // Locale code
    $purchaseAmount, // Max amount
    PayPalBool::false(),// No Shipping
    PayPalBool::false(), // Overide address
    PayPalBool::false(), // Requere confirmed shipping
    'http://sppdemoshop.eu/test/paypal_confirm.php?way=confirmed&order_id=' . $merchantReferenceId, //Return URL. See chapter “Success / Failure URL Handling” for more info
    'http://sppdemoshop.eu/test/paypal_confirm.php?way=cancelled&order_id=' . $merchantReferenceId // error url
);

$txnDetails  = new TxnDetails(new Amount($purchaseAmount), $merchantReferenceId);
$transaction = new Transaction($txnDetails, $payPalTxn);
$request = new SetExpressCheckoutRequest($transaction, null);

$response = $spp->getPayPalGateway()->initPayment(
    $request,
    new Swedbank_Ordering_Handler_PaymentCompletedCallback(
        $merchantReferenceId
    )
);

$url = $response->getCustomerRedirectUrl(false); // Getting redirect url. False - if test enviroment, true - if live enviroment

header('Location: ' . $url); // redirecting card holder to card input form.

paypal_confirm.php

include dirname(__FILE__).'/../SwedbankPaymentPortal/vendor/autoload.php';

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;
use SwedbankPaymentPortal\SharedEntity\Amount;
use SwedbankPaymentPortal\PayPal\CommunicationEntity\ShippingAddress;
use SwedbankPaymentPortal\PayPal\CommunicationEntity\SetExpressCheckoutRequest\Transaction;
use SwedbankPaymentPortal\PayPal\CommunicationEntity\SetExpressCheckoutRequest\Transaction\TxnDetails;
use SwedbankPaymentPortal\PayPal\CommunicationEntity\SetExpressCheckoutRequest\SetExpressCheckoutRequest;
use SwedbankPaymentPortal\PayPal\Type\PayPalBool;

include dirname(__FILE__) . '/callback.php';
include dirname(__FILE__) . '/logger.php';


$orderId = $_GET['order_id'];
$way  = $_GET['way'];

if ($way == 'confirmed'){
  $auth = new Authentication('*********', '*********');
  $options = new ServiceOptions(
      new CommunicationOptions(
        'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
		// for production/live use this URL: https://mars.transaction.datacash.com/Transaction
      ),
   $auth, new Swedbank_Client_Logger()
  );
  SwedbankPaymentPortal::init($options);  // <- library  initiation
  $spp = SwedbankPaymentPortal::getInstance();  // <- library usage

  $spp->getPayPalGateway()->handlePendingTransaction($orderId); 
  // now you can show user "thank you for your payment, but don't put flag 
  //flag need to put inside callback
  
  echo 'Thank you';
} else { // cancelled
	echo 'Payment cancelled';
	// do some action for cancel logic
}

调试/记录xml

要记录xml,需要修改代码。

include 'swedbank_logger.php';

将日志记录对象添加到ServiceOptions

$options = new ServiceOptions(
      new CommunicationOptions(
        'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
		// for production/live use this URL: https://mars.transaction.datacash.com/Transaction
      ),
   $auth, new Swedbank_Client_Logger()
  );

swedbank_logger.php

use SwedbankPaymentPortal\Logger\LoggerInterface;

class Swedbank_Client_Logger implements LoggerInterface
{
    public function __construct()
    {
    }

    /**
     * @param string                                                                                                                                                                                                                                                                                                                                                 $requestXml
     * @param string                                                                                                                                                                                                                                                                                                                                                 $responseXml
     * @param object|\SwedbankPaymentPortal\BankLink\CommunicationEntity\HPSQueryRequest\HPSQueryRequest|\SwedbankPaymentPortal\BankLink\CommunicationEntity\PaymentAttemptRequest\PaymentAttemptRequest|\SwedbankPaymentPortal\BankLink\CommunicationEntity\PurchaseRequest\PurchaseRequest|\SwedbankPaymentPortal\BankLink\CommunicationEntity\TransactionQueryRequest\TransactionQueryRequest $requestObject
     * @param object|\SwedbankPaymentPortal\BankLink\CommunicationEntity\PaymentAttemptResponse\PaymentAttemptResponse|\SwedbankPaymentPortal\BankLink\CommunicationEntity\PurchaseResponse\PurchaseResponse|\SwedbankPaymentPortal\BankLink\CommunicationEntity\TransactionQueryResponse\TransactionQueryResponse|\SwedbankPaymentPortal\SharedEntity\HPSQueryResponse\HPSQueryResponse         $responseObject
     * @param \SwedbankPaymentPortal\SharedEntity\Type\TransportType                                                                                                                                                                                                                                                                                                        $type
     */
    public function logData(
        $requestXml,
        $responseXml,
        $requestObject,
        $responseObject,
        \SwedbankPaymentPortal\SharedEntity\Type\TransportType $type
    ) {

        $requestType = $type->id();
        $request = $this->prettyXml($requestXml);
        $response = $responseXml;

		file_put_contents(dirname(__FILE__) . '/../../../storage/logs/swedbank.log', "\n-----\n$requestType\n$request\n\n$response\n", FILE_APPEND | LOCK_EX);
    }

    /**
     * Method formats given XML into pretty readable format
     *
     * @param $xml
     *
     * @return string
     */
    private function prettyXml($xml)
    {
        $doc = new DomDocument('1.0');
        $doc->loadXML($xml);
        $doc->preserveWhiteSpace = false;
        $doc->formatOutput       = true;

        $prettyXml = $doc->saveXML();

        return $prettyXml;
    }
}

查询卡支付

query_example.php

namespace SwedbankPaymentPortal;
// in autoloader and library needed for HPS payment
include dirname(__FILE__).'/vendor/autoload.php'; 

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;


$auth = new Authentication('xxxxxxxxxx','xxxxxxxxxx'); // VtID and password

//Merchant referance was used for payment
$merchantReferenceId = 'XXXXXXXXXXX'; 

$options = new ServiceOptions(
   new CommunicationOptions(
       'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
   	// for production/live use this URL: https://mars.transaction.datacash.com/Transaction
   ),
  $auth
);

SwedbankPaymentPortal::init($options);  // <- library  initiation
$spp = SwedbankPaymentPortal::getInstance();  // <- library usage

$response = $spp->getPaymentCardHostedPagesGateway()->query($merchantReferenceId);

取消或退款卡支付

cancel_example.php

namespace SwedbankPaymentPortal;
// in autoloader and library needed for HPS payment
include dirname(__FILE__).'/vendor/autoload.php'; 

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;


$auth = new Authentication('xxxxxxxxxx','xxxxxxxxxx'); // VtID and password

//Merchant referance was used for payment
$merchantReferenceId = 'XXXXXXXXXXX'; 

$options = new ServiceOptions(
   new CommunicationOptions(
       'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment 
   	// for production/live use this URL: https://mars.transaction.datacash.com/Transaction
   ),
  $auth
);

SwedbankPaymentPortal::init($options);  // <- library  initiation
$spp = SwedbankPaymentPortal::getInstance();  // <- library usage

$response = $spp->getPaymentCardHostedPagesGateway()->query($merchantReferenceId);

//var_dump($response);
$response = $spp->getPaymentCardHostedPagesGateway()->hpsCancel($response['QueryTxnResult']['datacash_reference']);
//check if cancell was successful if not do refund

//$response = $spp->getPaymentCardHostedPagesGateway()->hpsRefund($response['QueryTxnResult']['datacash_reference'], '3.23');

退款卡支付

refund.php

// in autoloader and library needed for HPS payment
include dirname(__FILE__) . '/SwedbankPaymentPortal/vendor/autoload.php';

use SwedbankPaymentPortal\Options\CommunicationOptions;
use SwedbankPaymentPortal\Options\ServiceOptions;
use SwedbankPaymentPortal\SharedEntity\Authentication;
use SwedbankPaymentPortal\SwedbankPaymentPortal;


$auth = new Authentication('***********','***********'); // VtID and password

//Merchant referance was used for payment
$merchantReferenceId = 'XXXXXXXXXXXXXXX';

$options = new ServiceOptions(
    new CommunicationOptions(
        'https://accreditation.datacash.com/Transaction/acq_a' //this is test environment
    // for production/live use this URL: https://mars.transaction.datacash.com/Transaction
    ),
    $auth
);

SwedbankPaymentPortal::init($options);  // <- library  initiation
$spp = SwedbankPaymentPortal::getInstance();  // <- library usage

$response = $spp->getPaymentCardHostedPagesGateway()->query($merchantReferenceId);

$ref = $response['QueryTxnResult']['datacash_reference'];
var_dump($ref); //string(16) "3400900025177762"

$amount = $response['QueryTxnResult']['amount'];
var_dump($amount); //string(5) "10.00"

//
$response = $spp->getPaymentCardHostedPagesGateway()->hpsRefund($ref, '0.50');
//Read parameter "status" if status == ACCEPTED then OK else failed
var_dump($response);
/*
 array(10) {
  ["@attributes"]=>
  array(1) {
    ["version"]=>
    string(1) "2"
  }
  ["MAC"]=>
  array(1) {
    ["outcome"]=>
    string(6) "ACCEPT"
  }
  ["acquirer"]=>
  string(22) "Swedbank Baltic Latvia"
  ["datacash_reference"]=>
  string(16) "3300900025177767"
  ["merchantreference"]=>
  string(16) "3400900025177762"
  ["mid"]=>
  string(10) "1000000000"
  ["mode"]=>
  string(4) "LIVE"
  ["reason"]=>
  string(8) "ACCEPTED"
  ["status"]=>
  string(1) "1"
  ["time"]=>
  string(10) "1549357106"
}
 */

$response = $spp->getPaymentCardHostedPagesGateway()->hpsRefund($ref, '15.00');

var_dump($response);
//Read parameter "status" if status == ACCEPTED then OK else failed
/*
 array(7) {
  ["@attributes"]=>
  array(1) {
    ["version"]=>
    string(1) "2"
  }
  ["datacash_reference"]=>
  string(16) "3900900025177769"
  ["merchantreference"]=>
  string(16) "3400900025177762"
  ["mode"]=>
  string(4) "LIVE"
  ["reason"]=>
  string(26) "Refund amount > orig 10.00"
  ["status"]=>
  string(2) "34"
  ["time"]=>
  string(10) "1549357108"
}
 */

$response = $spp->getPaymentCardHostedPagesGateway()->hpsRefund($ref, '2.00');
//Read parameter "status" if status == ACCEPTED then OK else failed
var_dump($response);
/*
 array(10) {
  ["@attributes"]=>
  array(1) {
    ["version"]=>
    string(1) "2"
  }
  ["MAC"]=>
  array(1) {
    ["outcome"]=>
    string(6) "ACCEPT"
  }
  ["acquirer"]=>
  string(22) "Swedbank Baltic Latvia"
  ["datacash_reference"]=>
  string(16) "3700900025177770"
  ["merchantreference"]=>
  string(16) "3400900025177762"
  ["mid"]=>
  string(10) "1000000000"
  ["mode"]=>
  string(4) "LIVE"
  ["reason"]=>
  string(8) "ACCEPTED"
  ["status"]=>
  string(1) "1"
  ["time"]=>
  string(10) "1549357108"
}
 */