swedbank-spp / swedbank-payment-portal
The Swedbank Payment Portal API Library provides access to the online banking system through which e-commerce transactions can be initiated and fulfilled by facilitating the exchange of bank data.
Installs: 96 027
Dependents: 0
Suggesters: 0
Security: 0
Stars: 35
Watchers: 8
Forks: 21
Open Issues: 9
Requires
- doctrine/cache: ^1.6
- guzzlehttp/guzzle: ^5.0|^6.0|^7.0
- jms/serializer: ^1.1
- symfony/config: ^2.8|^3.0|^4.0|^5.0
- symfony/dependency-injection: ^2.8|^3.0|^4.0|^5.0
- symfony/yaml: ~2.8|~3.0|~4.0|~5.0
Requires (Dev)
- phpunit/phpunit: ^5.2
- dev-master
- v0.9.4.1
- v0.9.4
- v0.9.3
- v0.9.2
- v0.9.1
- v0.9.0
- v0.8.33
- v0.8.32
- v0.8.31
- v0.8.30
- v0.8.29
- v0.8.28
- v0.8.27
- v0.8.26
- v0.8.25
- v0.8.24
- v0.8.23
- v0.8.22
- v0.8.21
- v0.8.20
- v0.8.19
- v0.8.18
- v0.8.17
- v0.8.16
- v0.8.15
- v0.8.14
- v0.8.13
- v0.8.12
- v0.8.11
- v0.8.10
- v0.8.9
- v0.8.8
- v0.8.7
- v0.8.6
- v0.8.5
- v0.8.4
- v0.8.3
- v0.8.2
- v0.8.1
- v0.8.0
- dev-dev-symfony-4
This package is not auto-updated.
Last update: 2024-10-28 08:35:49 UTC
README
About
Swedbank developed and maintaining API library to help and speed up merchant integrations in to e-shop.
Benefit to merchant
Usually Swedbank Payment Portal integration is done using technical specification (API documentation). Developers need to analyse it, prepare specific software architecture, logic to send and receive payment request messages towards Swedbank Payment Portal. By having library developer can save lot of development time and just reuse code and logic already created by us. This greatly speed up integration process on Merchant side and of course substantially saving the integration costs.
This library supports Swedbank payment types:
- Cards integration type HPS;
- Banklinks;
- PayPal Express Checkout;
Requirements
Minimum PHP version required 7.1 and above.
Installation Instruction
Projects with composer installed
This is recommended way of installation. Add dependency in your composer.json
:
"require": { "swedbank-spp/swedbank-payment-portal": "^0.9" }
and run "composer update" in command prompt or shell.
Alternative you can execute "composer require swedbank-spp/swedbank-payment-portal" from your command prompt or shell.
Projects which doesn`t have composer installed
- First download composer to your project root folder ( https://getcomposer.org/composer.phar )
- Run command: php composer.phar init
- Press Enter until command completes ("composer.json" file will be created)
- Open "composer.json" and replace "require": {} with:
"require": { "swedbank-spp/swedbank-payment-portal": "^0.9" }
- Run command: php composer.phar update (after success "vendor" folder will be created)
- In your project index.php please include php line require_once(__DIR__.'/vendor/autoload.php'); that way you’ll register composer default autoloader to your project.
- Done. From now you can use Swedbank Payment Portal library.
Integration
Credentials
To be able to test Swedbank payment system you will need to get credentials for development and production environment. Only to test is enouth test credentials.
Banklink integration
Here is a sequence diagram which illustrates full banklink process. You can see that for Banklink integration you’ll need to call only three methods in a library “initPayment()”, “handlePendingTransaction()” and “checkPendingTransactions()”.
Notification
Notification is used by banks to inform merchants about transaction statuses. Event notifications are communicated via a POST to a pre-configured merchant event URL. This URL must be different from the success and failure URL’s specified in the purchase setup requests. Multiple event notification URL’s can be configured on your Payment Gateway account, should the merchant require these messages to be delivered to a number of locations. The format of these event notifications is XML. Upon successful delivery of an event notification to an event URL, the merchant application must acknowledge receipt of such notification with an OK post back response to the Payment Gateway. The event notification mechanism is utilised to notify merchants of payment event statuses throughout the lifecycle of a transaction. For Banklink purchase transactions, the following event notifications could be delivered: AUTHORISED, REQUIRES_INVESTIGATION, CANCELLED. When a merchant receives the above event notifications, they are expected to respond with the following XML: OK In the event that the Payment Gateway does not receive a confirmation of receipt, the gateway will retry multiple times to send the notification. Using SPP library you need to call BankLinkService.handleNotification($xmlData) method to handle notification. “handleNotification” will parse XML and updates appropriate transaction status in the system. Also callback which was given in “initPayment” will be called if transaction resolves. Security note: Notification URL must be known and be accessible only from SPP server IP address. Configure your server to deny all other requests to that URL.
Usage example:
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>"; }
Payment Card (HPS) integration
Payment Card HPS integration is the same as Banklink.
PayPal integration (Express Checkout)
PayPal integration is also the same as HPS and banklink.
Cron job operations
System should call “checkPendingTransactions” operation on each minute. This will trigger status checking of transactions which are in PENDING state. Status checking operation time for each transaction is not related to cron job calling interval. Each transaction is queried in 30 minutes intervals. These settings can be changed in a library. One exception is for Banklink payment of Nordea: The first status querying of Nordea transaction is done only after 1 minute when user hits success URL, and later querying (if needed) after 30 minutes. These pending transaction checking is done only for Banklink and Payment Card HPS pending transactions as these transactions in some circumstances cannot be directly resolved (e.g. user didn’t get redirected to success url due internet problems).
Testing
Test transactions can be performed by using the test data in this section to process test transactions. The response received from the Payment Gateway will depend on the card number used. The responses are simulated and are intended to allow testing of common scenarios when processing Credit and Debit cards.
It is recommended that the following scenarios are tested as a minimum:
- Successful Authorisation including 3-D Secure authentication with different amounts
- Unsuccessful Authorisation
- Failed 3-D Secure authentication
Each merchant must ensure the interaction between the Payment Gateway and their own e-commerce system is behaving as expected.
Below are card numbers that are behaving on a predefined way. They are an excellent help when integrating and in testing/debugging of various scenarios.
Please note – magic cards are provided for Accreditation only and NOT intended for use in the Production Environment.
MasterCard Test Data
Maestro Test Data
Visa Test Data
Test Data for 3-D Secure
Any of the magic card numbers can be used while integrating 3-D Secure. The response will be determined first by the 3-D Secure configuration on your account, and then by the expiry month of the test card number.
In order to generate specific responses, please use the card expiry month shown below:
All library is under “SwedbankPaymentPortal” namespace. Main entry point for a library is “SwedbankPaymentPortal” class.
Here is a short example how to initialize a library:
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);
After that you can retrieve all payment services which are needed.
Next step is to retrieve your needed payment service by calling one of a methods of “SwedbankPaymentPortal” object.
Example:
$paypal = $spp->getPayPalGateway(); $banklink = $spp->getBankLinkGateway(); $hps = $spp->getPaymentCardHostedPagesGateway();
Whatever service you’ll retrieve all services contains a method “initPayment” which is a main payment initialization point.
Update:
To help other which projects do not have any dependency containers we’ve added couple static methods in a library which helps for global library initialization.
SwedbankPaymentPortal::init(ServiceOptions $options); // you must call this once to initialize library $spp = SwedbankPaymentPortal::getInstance(); // method will return an object of SwedbankPaymentPortal.
Please use these methods if your system do not have any dependency container to simplify process.
Success / Failure URL Handling
Whatever payment method you’ll use there is a need to specify success/failure URL for each “initPayment” call.
Success or Failure URL should be your custom page with appropriate message to user. Swedbank Payment Portal will redirect a customer to that URL in case of success or failure of purchase operation. Swedbank Payment Portal library is using additional server to server verification of success or failure of operation so you must call one of methods which finalizes a payment inside a library:
$spp->getBankLinkGateway()->handlePendingTransaction($orderId); $spp->getPayPalGateway()->handlePendingTransaction($orderId); $spp->getPaymentCardHostedPagesGateway()->hpsQuery($orderId);
(please look at sequence diagrams above to see what library methods must be called on each step)
Finalization will trigger a callbacks which you’ve been given in “initPayment” method calls.
So, to fully complete a transaction you must know what payment method was used and what is an order ID of that payment and that information must be included in your success/failure URL. E.g: http://yoururl.com/success.html?payment=banklink&orderid={order_id}
Warning: entering to success URL doesn’t mean that purchase was 100% completed. Never do any order completion logic inside success url action! That logic must go in Callbacks.
Callback setup
The main idea is that purchase process is fully asynchronous and you’ll be notified some time in future by callback method which you’ve had given during payment initialization(“initPayment”). Here is a short description about what is a callback.
Callback is an object which has implemented CallbackInterface. CallbackInterface contains one method
public function handleFinishedTransaction( TransactionResult $transactionResult, TransactionFrame $transactionFrame, PaymentCardTransactionData $paymentCardTransactionData = null );
and it will be called when transaction resolves (success or failure).
$transactionResult can be one of these values TransactionResult::success(), TransactionResult::failure(), TransactionResult::unfinished().
$transactionFrame - contains a request and a response of a last request which determined success/failure.
$paymentCardTransactionData - contains payment card information (expiry date, pan, authorization code). This parameter is optional and will be available only on HPS or HCC payment methods.
Because transactions is asynchronous that callback will be called some time in future on the different process so callback must be a PHP serializable object and must implement serialize() and unserialize() methods.
When a library calls a “handleFinishedTransaction” it will unserialize a callback to it’s previous state (time when had called “initPayment”).
If you need some additional information inside “handleFinishedTransaction” call the best way is to pass that information in callback constructor and implement serialize which persists that data.
For example it can be invoice id, order id, user id and other information which is required for your operations after transaction completion.
Update:
We have included default implementation of CallbackInterface called `UrlCallback` which now on you can use as Callback in “initPayment” (for all payment methods).
Example:
$spp->getBankLinkGateway()->initPayment( $purchaseRequest, UrlCallback::create(“http://yourdomain.com/some_secret_complete_handler?order_id={$orderId}”) );
UrlCallback will call the given url using HTTP POST operation, with these POST fields: “status” one of these: SUCCESS or FAIL or UNFINISHED.
Security note: Thsi link should be secret and not accessable from outside. To improve security you need to add IP filtration for CalbackURL. The only IP allowed to call this URL should be 127.0.0.1
E-Receipt for Payment Card transactions
After payment card transaction completion the third argument of “handleFinishedTransaction” method will be set. Third argument will contain object of PaymentCardTransactionData.
“PaymentCardTransactionData” consists of:
- pan
- expiryDate
- authorzationCode
- merchantReference
- fulfillDate
This information must be included in e-receipt which must be generated after purchase using payment cards.
Banklink payments
Here is a table of available banks and what serviceType and paymentMethod you need to specify in purchase request:
Example how to initiate banklink payment:
$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 Handling” for more info ->setFailureUrl("SPP") ->setMerchantReference($merchantReferenceId) ->setLanguage("lt") ->setPageSetId(1) ->getPurchaseRequest(); $response = $spp->getBankLinkGateway()->initPayment( $purchaseRequest, new Swedbank_Ordering_Handler_PaymentCompletedCallback( $merchantReferenceId ) );
HPS Example using calback
Replace sppdemoshop.eu to your shop address.
callback.php This is example of callback. Callback function need be available in setup call and final process.
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 This is setup script
// 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 This is final payment process
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 }
HPS Example using UrlCalback
Replace sppdemoshop.eu to your shop address. Use this only if you can't use above example.
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 This file newer will be loaded in browser. This will be called by cron job.
$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 }
Bank link
Replace sppdemoshop.eu to your shop address.
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 Handling” for 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 example
Replace sppdemoshop.eu to your shop address.
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 }
Debugging / logging xml
To log xml needed to modify code.
include 'swedbank_logger.php';
Add logger object to 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 card payment
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 or Refund card payment
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 card payment
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" } */