syspay/merchant-sdk-php

SysPay PHP 商户 SDK

此包的官方仓库似乎已不存在,因此包已被冻结。

v0.2.0 2014-02-11 14:23 UTC

This package is not auto-updated.

Last update: 2020-04-14 15:22:23 UTC


README

安装

此库需要 php 5.2+ 以及 jsoncurl 扩展。

使用 Composer

开始使用我们的 SDK 并保持更新的最简单方法是将其添加到您的 composer 依赖项中

$ composer.phar require syspay/merchant-sdk-php dev-master

手动

获取此 SDK 的副本

$ git clone https://github.com/syspay/merchant-sdk-php.git

然后,包含我们的 loader.php

<?php
require_once('/path/to/loader.php');

请求 API

实现参考:[SysPay 处理 API](https://app.syspay.com/docs/api/merchant_api.html)

创建客户端

所有操作都是通过一个 客户端对象 的实例来请求的。

<?php
$client = new Syspay_Merchant_Client($username, $secret[, $baseUrl]);

要针对沙盒环境调用,可以将 $baseUrl 设置为 Syspay_Merchant_Client::BASE_URL_SANDBOX

信用卡支付请求(服务器到服务器)

请求类:[Syspay_Merchant_PaymentRequest](https://app.syspay.com/docs/merchant-sdk-php/class-Syspay_Merchant_PaymentRequest.html)

您请求对一个 付款 对一个 客户 在给定的 信用卡 上进行支付。

<?php
$paymentRequest = new Syspay_Merchant_PaymentRequest(Syspay_Merchant_PaymentRequest::FLOW_API);
$paymentRequest->setPaymentMethod(Syspay_Merchant_PaymentRequest::METHOD_CREDITCARD);
$paymentRequest->setBillingAgreement(true); // true means you want to be able to rebill this customer later. Defaults to false

$customer = new Syspay_Merchant_Entity_Customer();
$customer->setEmail('foo@bar.baz'); // Customer's email
$customer->setLanguage('en'); // Optional, used to send notifications in the correct language
$customer->setIp('1.2.3.4'); // Customer IP address
$paymentRequest->setCustomer($customer);

$creditcard = new Syspay_Merchant_Entity_Creditcard();
$creditcard->setHolder('John Doe');
$creditcard->setNumber('4111111111111111');
$creditcard->setCvc('123');
$creditcard->setExpMonth('01');
$creditcard->setExpYear('2014');
$paymentRequest->setCreditcard($creditcard);

$payment = new Syspay_Merchant_Entity_Payment();
$payment->setReference('1234567'); // Your own reference for this payment
$payment->setPreauth(true); // By default, we will process a DIRECT payment. Set this to true to PREAUTH only, it will then need to be confirmed later
$payment->setAmount(1000); // Amount in *cents*
$payment->setCurrency('EUR'); // Currency
$payment->setDescription('some description'); // An optional description
$payment->setExtra(json_encode($someInformation)); // An optional information that will given back to you on notifications
$paymentRequest->setPayment($payment);

$payment = $client->request($paymentRequest);
// $payment is an instance of Syspay_Merchant_Entity_Payment

托管支付请求

请求类:[Syspay_Merchant_PaymentRequest](https://app.syspay.com/docs/merchant-sdk-php/class-Syspay_Merchant_PaymentRequest.html)

<?php
$paymentRequest = new Syspay_Merchant_PaymentRequest(Syspay_Merchant_PaymentRequest::FLOW_BUYER);
$paymentRequest->setMode(Syspay_Merchant_PaymentRequest::MODE_ONLINE); // Refer to the documentation for the 'terminal' mode
$paymentRequest->setBillingAgreement(true); // true means you want to be able to rebill this customer later. Defaults to false

// Assigning a customer to the request is optional on the hosted flow but recommended to pre-fill the payment form
$customer = new Syspay_Merchant_Entity_Customer();
$customer->setEmail('foo@bar.baz'); // Customer's email
$customer->setLanguage('en'); // Used to send notifications in the correct language and overwrite the payment page language (by default it tries to accomodate the browser settings)
$paymentRequest->setCustomer($customer);

$payment = new Syspay_Merchant_Entity_Payment();
$payment->setReference('1234567'); // Your own reference for this payment
$payment->setAmount(1000); // Amount in *cents*
$payment->setCurrency('EUR'); // Currency
$payment->setDescription('some description'); // An optional description
$payment->setExtra(json_encode($someInformation)); // An optional information that will given back to you on notifications
$paymentRequest->setPayment($payment);

$payment = $client->request($paymentRequest);
// $payment is an instance of Syspay_Merchant_Entity_Payment, you can now redirect your customer to $payment->getRedirect()

确认授权的付款

请求类:[Syspay_Merchant_ConfirmRequest](https://app.syspay.com/docs/merchant-sdk-php/class-Syspay_Merchant_ConfirmRequest.html)

<?php
$confirmRequest = new Syspay_Merchant_ConfirmRequest();
$confirmRequest->setPaymentId($originalPaymentId); // Returned to you on the initial payment request

$confirm = $client->request($confirmRequest);
// $confirm is an instance of Syspay_Merchant_Entity_Payment

取消授权的付款

请求类:[Syspay_Merchant_VoidRequest](https://app.syspay.com/docs/merchant-sdk-php/class-Syspay_Merchant_VoidRequest.html)

<?php
$voidRequest = new Syspay_Merchant_VoidRequest();
$voidRequest->setPaymentId($originalPaymentId); // Returned to you on the initial payment request

$void = $client->request($voidRequest);
// $void is an instance of Syspay_Merchant_Entity_Payment

获取关于付款的信息

请求类:[Syspay_Merchant_PaymentInfoRequest](https://app.syspay.com/docs/merchant-sdk-php/class-Syspay_Merchant_PaymentInfoRequest.html)

<?php
$infoRequest = new Syspay_Merchant_PaymentInfoRequest($paymentId);

$payment = $client->request($infoRequest);
// $payment is an instance of Syspay_Merchant_Entity_Payment

导出付款列表

请求类:[Syspay_Merchant_PaymentListRequest](https://app.syspay.com/docs/merchant-sdk-php/class-Syspay_Merchant_PaymentListRequest.html) 可用的过滤器列表可以在我们的 [API 文档](https://app.syspay.com/bundles/emiuser/doc/merchant_api.html#get-a-list-of-payments) 中找到。

<?php
$paymentListRequest = new Syspay_Merchant_PaymentListRequest();
// Optionally set filters (refer to the API documentation for an exhaustive list)
$paymentListRequest->addFilter('start_date', $someTimestamp);
$paymentListRequest->addFilter('end_date', $someOtherTimestamp);

$payments = $client->request($paymentListRequest);
// $payments is an array of Syspay_Merchant_Entity_Payment

退款

请求类: Syspay_Merchant_RefundRequest

您请求对一个特定的 支付ID 进行 退款

<?php
$refund = new Syspay_Merchant_Entity_Refund();
$refund->setReference('1234567'); // Your own reference for this refund
$refund->setAmount(1000); // The amount to refund in *cents*
$refund->setCurrency('EUR'); // The currency of the refund. It must match the one of the original payment
$refund->setDescription('some description'); // An optional description for this refund
$refund->setExtra(json_encode($someInformation)); // An optional information that will be given back to you on notifications

$refundRequest = new Syspay_Merchant_RefundRequest();
$refundRequest->setPaymentId($paymentId); // The payment id to refund
$refundRequest->setRefund($refund);

$refund = $client->request($refundRequest);
// $refund is an instance of Syspay_Merchant_Entity_Refund

获取退款信息

请求类: Syspay_Merchant_RefundInfoRequest

<?php
$infoRequest = new Syspay_Merchant_RefundInfoRequest($refundId);

$refund = $client->request($infoRequest);
// $refund is an instance of Syspay_Merchant_Entity_Refund

导出退款列表

请求类: Syspay_Merchant_RefundListRequest 可用的过滤器列表可在我们的 API 文档 中找到

<?php
$refundListRequest = new Syspay_Merchant_RefundListRequest();
// Optionally set filters (refer to the API document for an exhaustive list)
$paymentListRequest->addFilter('status', 'SUCCESS');

$refunds = $client->request($refundListRequest);
// $refunds is an array of Syspay_Merchant_Entity_Refund

在给定的账单协议上重新扣款

请求类: Syspay_Merchant_RebillRequest

<?php
// The billing agreement id returned from the initial payment request must be used
$rebillRequest = new Syspay_Merchant_RebillRequest($billingAgreementId);
$rebillRequest->setAmount(1000); // Amount in *cents*
$rebillRequest->setCurrency('EUR'); // This is used as security and must match the currency that was used to create the billing agreement
$rebillRequest->setReference('123456'); // Your own reference for this payment
$rebillRequest->setDescription('some description'); // An optional description
$rebillRequest->setExtra(json_encode($someInformation)); // An optional information that will given back to you on notifications
$rebillRequest->setEmsUrl('https://foo.bar/baz'); // An optional EMS url the notifications will be posted to if you don't want to use the default one

$payment = $client->request($rebillRequest);
// $payment is an instance of Syspay_Merchant_Entity_Payment

获取账单协议信息

请求类: Syspay_Merchant_BillingAgreementInfoRequest

<?php
$infoRequest = new Syspay_Merchant_BillingAgreementInfoRequest($billingAgreementId);

$billingAgreement = $client->request($infoRequest);
// $billingAgreement is an instance of Syspay_Merchant_Entity_BillingAgreement

取消账单协议

请求类: Syspay_Merchant_BillingAgreementCancellationRequest

<?php
$cancellationRequest = new Syspay_Merchant_BillingAgreementCancellationRequest($billingAgreemntId);

$billingAgreement = $client->request($cancellationRequest);
// $billingAgreement is an instance of Syspay_Merchant_Entity_BillingAgreement

导出账单协议列表

请求类: Syspay_Merchant_BillingAgreementListRequest 可用的过滤器列表可在我们的 API 文档 中找到

<?php
$billingAgreementsRequest = new Syspay_Merchant_BillingAgreementListRequest();
// Optionally set filters (refer to the API document for an exhaustive list)
$billingAgreementsRequest->addFilter('status', 'ACTIVE');

$billingAgreements = $client->request($billingAgreementsRequest);
// $billingAgreements is an array of Syspay_Merchant_Entity_BillingAgreement

获取退单信息

请求类: Syspay_Merchant_ChargebackInfoRequest

<?php
$infoRequest = new Syspay_Merchant_ChargebackInfoRequest($chargebackId);

$chargeback = $client->request($infoRequest);
// $chargeback is an instance of Syspay_Merchant_Entity_Chargeback

导出退单列表

请求类: Syspay_Merchant_ChargebackListRequest 可用的过滤器列表可在我们的 API 文档 中找到

<?php
$chargebackListRequest = new Syspay_Merchant_ChargebackListRequest();
// Optionally set filters (refer to the API document for an exhaustive list)
$paymentListRequest->addFilter('email', 'foo@bar.baz');

$chargebacks = $client->request($chargebackListRequest);
// $chargebacks is an array of Syspay_Merchant_Entity_Chargeback

获取Syspay IP地址

请求类: Syspay_Merchant_IpAddressesRequest

<?php
$ipRequest = new Syspay_Merchant_IpAddressesRequest();

$ips = $client->request($ipRequest);
// $ips is an array of strings (ips)

创建订阅或分期计划

请求类: Syspay_Merchant_PlanRequest

订阅和分期计划的区别主要有

  • 对于分期计划,您提供总额和周期数,我们将负责分割总付款。
  • 分期付款计划不支持试用期也不支持不同的首付款金额。如果您需要这些功能,您将不得不使用订阅。
  • 分期付款计划在最后一次付款完成后结束,而订阅将在最后一次付款后结束一个“周期”。

示例 1:1 欧元的 2 周试用期,之后每月自动支付 30 欧元,直到取消订阅

<?php
$plan = new Syspay_Merchant_Entity_Plan();
$plan->setType(Syspay_Merchant_Entity_Plan::TYPE_SUBSCRIPTION);
$plan->setName('Product 01');
$plan->setDescription('2 weeks for 1EUR / 30EUR monthly');
$plan->setCurrency('EUR');

// Trial is 1 time 15 minutes at 1 EUR
$plan->setTrialAmount(100); // Amounts are in cents
$plan->setTrialCycles(1);
$plan->setTrialPeriod(2);
$plan->setTrialPeriodUnit(Syspay_Merchant_Entity_Plan::UNIT_WEEK);
// Billing is until unsubscription (0 cycles), every 1 month
$plan->setBillingCycles(0);
$plan->setBillingAmount(3000);
$plan->setBillingPeriod(1);
$plan->setBillingPeriodUnit(Syspay_Merchant_Entity_Plan::UNIT_MONTH);

$planRequest = new Syspay_Merchant_PlanRequest();
$planRequest->setPlan($plan);
$plan = $client->request($planRequest);
// $plan is an instance of Syspay_Merchant_Entity_Plan

示例 2:没有试用期,但首付款为 45 欧元,之后每两个月支付 20 欧元 3 次

在这种情况下,共有 4 个账单周期,包括首付款周期,金额不同。

<?php
$plan = new Syspay_Merchant_Entity_Plan();
$plan->setType(Syspay_Merchant_Entity_Plan::TYPE_SUBSCRIPTION);
$plan->setName('Product 02');
$plan->setDescription('45 initial / 3 * 20 EUR');
$plan->setCurrency('EUR');

// 4 Billing cycles of 20 EUR, except for the initial one
$plan->setBillingCycles(4);
$plan->setInitialAmount(4500);
$plan->setBillingAmount(2000);
$plan->setBillingPeriod(2);
$plan->setBillingPeriodUnit(Syspay_Merchant_Entity_Plan::UNIT_MONTH);

$planRequest = new Syspay_Merchant_PlanRequest();
$planRequest->setPlan($plan);
$plan = $client->request($planRequest);
// $plan is an instance of Syspay_Merchant_Entity_Plan

示例 3:分期付款计划,每月支付 100 欧元 3 次

<?php
$plan = new Syspay_Merchant_Entity_Plan();
$plan->setType(Syspay_Merchant_Entity_Plan::TYPE_INSTALMENT);
$plan->setName('Product 03');
$plan->setDescription('100 EUR in 3 months');
$plan->setCurrency('EUR');

// 3 billing cycles of 1 month, 100 EUR to take
// Note: This will create 1 payment of 33.34 and 2 payments of 33.33 EUR
$plan->setBillingCycles(3);
$plan->setTotalAmount(10000);
$plan->setBillingPeriod(1);
$plan->setBillingPeriodUnit(Syspay_Merchant_Entity_Plan::UNIT_MONTH);

$planRequest = new Syspay_Merchant_PlanRequest();
$planRequest->setPlan($plan);
$plan = $client->request($planRequest);
// $plan is an instance of Syspay_Merchant_Entity_Plan

将客户订阅到计划

请求类: Syspay_Merchant_SubscriptionRequest

与标准付款一样,有两种方式可以将用户订阅到计划

  • 托管:在这种情况下,将返回一个链接给您。您需要将客户重定向到该链接以完成付款。
  • 服务器到服务器:您将客户和付款信息以及订阅数据发送给我们,付款将即时处理。如果需要重定向以完成付款(例如 3DS),则此 URL 将返回给您,以便您可以重定向客户以完成付款。

在这两种情况下,订阅将在首付款完成或失败时开始(变为活动状态)。

示例 1:托管付款页面

<?php
// You must at least provide the customer's email
$customer = new Syspay_Merchant_Entity_Customer();
$customer->setEmail('your@customer.com');
$customer->setLanguage('fr');

$subscription = new Syspay_Merchant_Entity_Subscription();
$subscription->setPlanId(61); // The id of the plan to subscribe to
$subscription->setReference('123456'); // Your own reference for this subscription (and all the payments that will be linked to it)
$subscription->setExtra(json_encode($someInformation)); // An optional information that will be given back to you on notifications

$subscriptionRequest = new Syspay_Merchant_SubscriptionRequest();
$subscriptionRequest->setSubscription($subscription);
$subscriptionRequest->setFlow(Syspay_Merchant_SubscriptionRequest::FLOW_BUYER); // Hosted payment page
$subscriptionRequest->setCustomer($customer);

$subscription = $client->request($subscriptionRequest);
// $subscription is an instance of Syspay_Merchant_Entity_Subscription
// The link to redirect the customer to will be available in $subscription->getRedirect();

示例 2:服务器到服务器

<?php
// For server-2-server we require you to send the customer's IP
$customer = new Syspay_Merchant_Entity_Customer();
$customer->setEmail('your@customer.com');
$customer->setLanguage('fr'); // Defaults to english
$customer->setIp('1.2.3.4'); // Mandatory for server-2-server flow

$creditcard = new Syspay_Merchant_Entity_Creditcard();
$creditcard->setHolder('John Doe');
$creditcard->setNumber('4111111111111111');
$creditcard->setCvc('123');
$creditcard->setExpMonth('01');
$creditcard->setExpYear('2015');

$subscription = new Syspay_Merchant_Entity_Subscription();
$subscription->setPlanId(61); // The id of the plan to subscribe to
$subscription->setReference(uniqid()); // Your own reference for this subscription (and all the payments that will be linked to it)
$subscription->setExtra(json_encode($someInformation)); // An optional information that will be given back to you on notifications

$subscriptionRequest = new Syspay_Merchant_SubscriptionRequest();
$subscriptionRequest->setSubscription($subscription);
$subscriptionRequest->setFlow(Syspay_Merchant_SubscriptionRequest::FLOW_API); // server-2-server flow
$subscriptionRequest->setCustomer($customer);

// Use the created creditcard to pay
$subscriptionRequest->setPaymentMethod(Syspay_Merchant_Entity_PaymentMethod::TYPE_CREDITCARD);
$subscriptionRequest->setCreditcard($creditcard);

$subscription = $client->request($subscriptionRequest);
// $subscription is an instance of Syspay_Merchant_Entity_Subscription
// The subscription will be ACTIVE on success, CANCELLED on failure, or PENDING if there is a redirect to do

在订阅上发起手动续费

请求类: Syspay_Merchant_SubscriptionRebillRequest

<?php
$rebillRequest = new Syspay_Merchant_SubscriptionRebillRequest($subscriptionId);
$rebillRequest->setAmount(4200);
$rebillRequest->setCurrency('EUR');
$rebillRequest->setExtra('foobarbaz'); // optional, will use the subscription's if not defined
$rebillRequest->setDescription('Extra credits'); // optional, will use the plan's if not defined
$rebillRequest->setReference(12345); // optional, will use the subscription's if not defined
$rebillRequest->setEmsUrl('https://merchant.com/notification'); // optional, will use the subscription's if not defined
$payment = $client->request($cancelRequest);
// $payment is an instance of Syspay_Merchant_Entity_Payment

取消订阅或分期付款计划

请求类: Syspay_Merchant_SubscriptionCancellationRequest

默认情况下,取消订阅将允许其运行到当前周期结束,并在付款失败时重新尝试最后付款。

<?php
$cancelRequest = new Syspay_Merchant_SubscriptionCancellationRequest($subscriptionId);
$subscription = $client->request($cancelRequest);
// $subscription is an instance of Syspay_Merchant_Entity_Subscription

如果您想立即终止订阅并取消任何失败的付款的进一步重试,可以将 now 属性设置为 true。


<?php
$cancelRequest = new Syspay_Merchant_SubscriptionCancellationRequest($subscriptionId);
$cancelRequest->setNow(true);
$subscription = $client->request($cancelRequest);
// $subscription is an instance of Syspay_Merchant_Entity_Subscription

获取计划信息

请求类: Syspay_Merchant_PlanInfoRequest

<?php
$planInfoRequest = new Syspay_Merchant_PlanInfoRequest($planId);
$plan = $client->request($planInfoRequest);
// $plan is an instance of Syspay_Merchant_Entity_Plan

获取订阅信息

请求类: Syspay_Merchant_SubscriptionInfoRequest

<?php
$subInfoRequest = new Syspay_Merchant_SubscriptionInfoRequest($subscriptionId);
$subscription = $client->request($subInfoRequest);
// $subscription is an instance of Syspay_Merchant_Entity_Subscription

处理托管支付页面和3DS重定向

当支付需要重定向时(无论是需要3DS验证的服务器到服务器支付,还是使用托管支付页面流程时),您将无法同步知道交易的结果。

相反,一旦交易被处理,客户将被重定向回您的网站(无论是您的默认重定向url,还是您根据请求设置的url),同时附带额外的参数,这些参数将通知您交易的结果。

为了使您更容易验证这些额外的参数并提取信息,您可以使用Syspay_Merchant_Redirect处理器。它将检查参数是否被篡改,并返回一个支付对象。

注意:如果客户没有回到您的网站(例如,他在托管支付确认页面上关闭浏览器),您仍然会通过我们的EMS系统(在下一章中描述)通知支付状态

示例处理器

<?php

require '/path/to/merchant-sdk-php/loader.php';

// You might have multiple merchant credentials that all point to the same EMS url
$secrets = array(
    'login_1' => 'secret_1',
    'login_2' => 'secret_2'
);

try {
    $redirect = new Syspay_Merchant_Redirect($secrets);
    // The getResult method takes an array as input. This array must contain the 'result', 'merchant' and 'checksum' request parameters
    $payment = $redirect->getResult($_REQUEST);
} catch (Syspay_Merchant_RedirectException $e) {
    // If an error status is sent, syspay will try again to deliver the message several times.
    header(':', true, 500);
    printf("Something went wrong while processing the message: (%d) %s\n",
                $e->getCode(), $e->getMessage());
}

接收EMS通知

实现参考:SysPay事件消息系统

Syspay_Merchant_EMS类将自动验证HTTP头并解析事件,以返回相关对象。

目前支持的事件有

如果发生错误,将抛出一个Syspay_Merchant_EMSException,并包含以下代码之一

  • Syspay_Merchant_EMSException::CODE_MISSING_HEADER:找不到X-Merchant和/或X-Checksum
  • Syspay_Merchant_EMSException::CODE_INVALID_CHECKSUMX-Checksum头无法验证提供的密钥
  • Syspay_Merchant_EMSException::CODE_INVALID_CONTENT:无法解析请求内容
  • Syspay_Merchant_EMSException::CODE_UNKNOWN_MERCHANT:存在X-Merchant头,但在构造函数传递的数组中找不到

示例监听器

<?php

require '/path/to/merchant-sdk-php/loader.php';

// You might have multiple merchant credentials that all point to the same EMS url
$secrets = array(
    'login_1' => 'secret_1',
    'login_2' => 'secret_2'
);

$ems = new Syspay_Merchant_EMS($secrets);

try {
    $event = $ems->getEvent();
    switch ($event->getType()) {
        case 'payment':
            printf("Payment %d received, status: %s\n", $event->getId(), $event->getStatus());
            break;
        case 'refund':
            printf("Refund %d received, status: %s\n", $event->getId(), $event->getStatus());
            break;
        case 'chargeback':
            printf("Chargeback %d received, status: %s\n", $event->getId(), $event->getStatus());
            break;
        case 'billing_agreement':
            printf("Billing Agreement %d received, status: %s\n", $event->getId(), $event->getStatus());
            break;
        case 'subscription':
            printf("Subscription %d received, status: %s, phase: %s\n", $event->getId(), $event->getStatus(), $event->getPhase());
            break;
    }
} catch (Syspay_Merchant_EMSException $e) {
    // If an error status is sent, syspay will try again to deliver the message several times
    header(':', true, 500);
    printf("Something went wrong while processing the message: (%d) %s",
                $e->getCode(), $e->getMessage());
}