sv-eaekonomi / checkout
Svea Checkout的PHP集成库
Requires
- php: >=5.3.0
- ext-curl: *
Requires (Dev)
- phploc/phploc: ^2.0.1
- phpmd/phpmd: ^2.4
- phpunit/phpunit: ~4.8 || ~5.5
- satooshi/php-coveralls: ~1.0
- sebastian/phpcpd: ^2.0.4
- squizlabs/php_codesniffer: 2.*
- symfony/dependency-injection: ^2.7.51 || ^2.8.50 || ^3.4.26 || ^4.1.12 || ^4.2.7
This package is auto-updated.
Last update: 2024-09-25 11:45:20 UTC
README
索引
- 1. 设置
- 2. 通用信息
- 3. 创建订单
- 4. 获取订单
- 5. 更新订单
- 6. 创建周期性订单
- 7. 获取周期性订单
- 8. 响应
- 9. 其他请求
- 10. 数据结构
- 11. HttpStatusCodes
- 12. 订单管理
- 13. JavaScript API
简介
结账提供了多种支付方式的全套解决方案。结账中目前可用的支付方式包括发票、分期付款、账户信用、信用卡支付和银行支付。
结账支持B2C和B2B支付,快速客户识别并缓存客户行为。
此库提供入口点以将结账集成到您的平台并管理结账订单。
测试凭证
您可以在此处找到可以在不与Svea Bank签订合同的情况下用于测试环境的凭证
示例文件还包含可在测试环境中使用的商家凭证。
1. 设置
1.1 使用Composer安装
在您的命令行界面中执行以下行
composer require sveaekonomi/checkout
或将其添加到您的composer.json中
{ "require": { "sveaekonomi/checkout": "dev-master" } }
然后在您的CLI中运行命令 composer update
1.2 不使用composer安装
您还可以下载库并将其上传到您的服务器。
2. 通用信息
2.1 创建连接器
当创建CheckoutClient或CheckoutAdminClient对象时,您必须使用连接器对象作为参数,这些对象用于创建API请求。
连接器定义了应使用哪些凭证以及应使用哪个环境。
创建连接器的参数:checkoutMerchantId、checkoutSecret和基础API URL(环境)。
// include the library include 'vendor/autoload.php'; // include library without composer, include.php is in the library root require_once 'include.php'; $checkoutMerchantId = '100001'; $checkoutSecret = 'checkoutSecret'; //set endpoint url. Eg. test or prod $baseUrl = \Svea\Checkout\Transport\Connector::TEST_BASE_URL; $connector = \Svea\Checkout\Transport\Connector::init($checkoutMerchantId, $checkoutSecret, $baseUrl);
2.2 CheckoutClient
CheckoutClient类包含四个方法,可用于
- 创建订单 - 创建Svea Checkout订单
- 更新订单 - 更新现有的Svea Checkout订单
- 获取订单 - 从现有订单获取订单数据
- 获取分期付款活动 - 获取可用于在产品页面上显示每月价格的营销活动
为确保始终向最终用户显示片段,我们建议在您的平台中使用以下流程
2.3 CheckoutAdminClient
CheckoutAdminClient类包含用于管理使用CheckoutClient类创建的订单的方法。
只有当CheckoutOrderStatus为“FINAL”时,才能管理订单,任何其他状态都表示订单尚未由最终客户最终确定。
为了在订单上执行操作,订单需要有一个操作。您必须使用“获取订单”获取订单并检查哪些操作可用,然后使用相应的函数。
例如,如果您想给订单加信用,首先必须使用获取订单。假设返回的操作是"CanCreditAmount",那么您将必须使用加信用额度来给订单加信用。
某些操作可能在某些订单类型上不可用,但一个好的集成不会检查订单类型,而是检查哪些操作可以用于。
可用的方法包括
- 获取订单 - 从支付管理员返回订单数据,包含CheckoutClient方法以外的其他信息
- 获取任务 - 返回先前执行的操作的状态
- 交付订单 - 在结账订单上创建交付(向最终客户发送发票等)
- 以较低金额交付订单 - 以较低金额在结账订单上创建交付(向最终客户发送发票等),取消剩余金额
- 取消订单 - 取消订单
- 取消订单金额 - 从订单中移除指定金额
- 取消订单行 - 从订单中移除订单行
- 给订单行加信用 - 在已交付的订单上给订单行加信用
- 给新订单行加信用 - 创建一个新的订单行,带有加信用的金额
- 给订单行加信用并收费 - 在已交付的订单上给订单行加信用并加收费用
- 加信用额度 - 给指定金额加信用
- 添加订单行 - 向订单中添加订单行
- 更新订单行 - 更新现有的订单行
- 替换订单行 - 将订单上的所有订单行替换为新订单行
3. 创建订单
要创建新订单,您需要实例化一个\Svea\Checkout\CheckoutClient对象,并将连接器作为参数传递。
然后您可以使用对象中的"create"方法,将以下数据传递给该方法。下面是示例。
响应将包含所有订单数据,以及包含需要渲染给最终用户的iframe的片段。
创建订单示例
// include the library include 'vendor/autoload.php'; // without composer require_once 'include.php'; $data = array( "countryCode" => "SE", "currency" => "SEK", "locale" => "sv-SE", "clientOrderNumber" => rand(10000,30000000), "merchantData" => "Test string from merchant", "cart" => array( "items" => array( array( "articleNumber" => "1234567", "name" => "Yellow rubber duck", "quantity" => 200, "unitPrice" => 12300, "discountPercent" => 1000, "vatPercent" => 2500, "unit" => "st", "temporaryReference" => "1", "merchantData" => "Size: S" ), array( "articleNumber" => "987654321", "name" => "Blue rubber duck", "quantity" => 500, "unitPrice" => 25000, "discountPercent" => 1000, "vatPercent" => 2500, "unit" => "pcs", "temporaryReference" => "2", "merchantData" => null ) ) ), "presetValues" => array( array( "typeName" => "emailAddress", "value" => "test@yourdomain.se", "isReadonly" => false ), array( "typeName" => "postalCode", "value" => "99999", "isReadonly" => false ) ), "merchantSettings" => array( "termsUri" => "http://yourshop.se/terms/", "checkoutUri" => "http://yourshop.se/checkout/", "confirmationUri" => "http://yourshop.se/checkout/confirm/", "pushUri" => "https://yourshop.se/push.php?checkout_order_id={checkout.order.uri}", ) ); $checkoutClient = new \Svea\Checkout\CheckoutClient($connector); $response = $checkoutClient->create($data);
4. 获取订单
要获取现有订单,您需要实例化一个\Svea\Checkout\CheckoutClient对象,并将连接器作为参数传递。
然后您可以使用对象中的"get"方法,将以下数据传递给该方法。下面是示例。
响应包含订单信息和GUI,可以使用它再次渲染iframe。
// include the library include 'vendor/autoload.php'; // without composer require_once 'include.php'; $data = array( 'orderId' => 51721 ); $checkoutClient = new \Svea\Checkout\CheckoutClient($connector); $response = $checkoutClient->get($data);
5. 更新订单
要更新现有订单,您需要实例化一个 \Svea\Checkout\CheckoutClient 对象,并将一个 连接器 作为参数传递。
此方法返回订单信息和用于显示 Svea Checkout 中 iframe 的更新后的 Gui。除非使用 JavaScript API,否则应将之前显示的 iframe 替换为更新订单时接收到的响应中的 iframe。
只有在 CheckoutOrderStatus 为 "已创建" 时,才能更新订单,请参阅 CheckoutOrderStatus。
如果使用 JS API 禁用 iframe,并在禁用的情况下更新订单,则在再次启用 iframe 时,它会更新一次。这消除了在订单更新后替换 iframe 的需求。
// include the library include 'vendor/autoload.php'; // without composer require_once 'include.php'; ... $checkoutClient = new \Svea\Checkout\CheckoutClient($connector); $data = array( "orderId" => 251147, "merchantData" => "test", "cart" => array( "items" => array( array( "articleNumber" => "123456", "name" => "Yellow rubber duck", "quantity" => 200, "unitPrice" => 66600, "discountPercent" => 1000, "vatPercent" => 2500, "temporaryReference" => "230", "merchantData" => "Size: M" ), array( "articleNumber" => "658475", "name" => "Shipping Fee Updated", "quantity" => 100, "unitPrice" => 4900, "vatPercent" => 2500, "temporaryReference" => "231", "merchantData" => null ) ) ) ); $response = $checkoutClient->update($data);
6. 创建周期性订单
为了创建定期订单,必须在您的商家中启用此功能。如果您想启用此功能,请联系 Svea。
要创建定期订单,您需要实例化一个 \Svea\Checkout\CheckoutClient 对象,并将一个 连接器 作为参数传递。在数据中,您必须指定在订单最终确定时返回的 定期令牌。
此操作使用 checkoutApi 并创建一个新订单,您稍后可以在 PaymentAdmin 中查看。
示例
// include the library include 'vendor/autoload.php'; // without composer require_once 'include.php'; ... $checkoutClient = new \Svea\Checkout\CheckoutClient($connector); $data = array( "token" => "12345678-90ab-cdef-1234-567890abcdef", "currency" => "SEK", "clientOrderNumber" => 12356, "merchantSettings" => array( "checkoutUri" => "http://yourshop.se/checkout/", "pushUri" => "https://yourshop.se/push.php?checkout_order_id={checkout.order.uri}", ), "cart" => array( "items" => array( array( "articleNumber" => "123456", "name" => "Yellow rubber duck", "quantity" => 200, "unitPrice" => 66600, "discountPercent" => 1000, "vatPercent" => 2500, "temporaryReference" => "230", "merchantData" => "Size: M" ), ) ) ); $response = $checkoutClient->create($data);
7. 获取周期性订单
为了获取定期订单,您需要传递创建订单时使用的令牌以及 orderId。请注意,此方法仅适用于先前使用 创建定期订单 方法创建的订单。您可以使用 获取订单 方法获取原始订单。
示例
// include the library include 'vendor/autoload.php'; // without composer require_once 'include.php'; $data = array( 'orderId' => 123456 'token' => '12345678-90ab-cdef-1234-567890abcdef' ); $checkoutClient = new \Svea\Checkout\CheckoutClient($connector); $response = $checkoutClient->get($data);
8. 响应
响应包含有关订单的信息,例如购物车、状态、支付类型等。
示例响应
Array ( [MerchantSettings] => Array ( [CheckoutValidationCallBackUri] => [PushUri] => https://yourdomain.se/push.php?svea_order_id={checkout.order.uri} [TermsUri] => http://yourdomain.se/terms [CheckoutUri] => http://yourdomain.se/checkout/ [ConfirmationUri] => http://yourdomain.se/checkout/confirm [ActivePartPaymentCampaigns] => Array ( ) [PromotedPartPaymentCampaign] => 0 ) [Cart] => Array ( [Items] => Array ( [0] => Array ( [ArticleNumber] => 1234567 [Name] => Yellow rubber duck [Quantity] => 200 [UnitPrice] => 66600 [DiscountPercent] => 1000 [VatPercent] => 2500 [Unit] => [TemporaryReference] => [RowNumber] => 1 [MerchantData] => Size: M ) [1] => Array ( [ArticleNumber] => 987654321 [Name] => Blue rubber duck [Quantity] => 500 [UnitPrice] => 25000 [DiscountPercent] => 1000 [VatPercent] => 2500 [Unit] => pcs [TemporaryReference] => [RowNumber] => 2 [MerchantData] => ) [2] => Array ( [ArticleNumber] => 6eaceaec-fffc-41ad-8095-c21de609bcfd [Name] => InvoiceFee [Quantity] => 100 [UnitPrice] => 2900 [DiscountPercent] => 0 [VatPercent] => 2500 [Unit] => st [TemporaryReference] => [RowNumber] => 3 [MerchantData] => ) ) ) [Customer] => Array ( [Id] => 626 [NationalId] => 194605092222 [CountryCode] => SE [IsCompany] => ) [ShippingAddress] => Array ( [FullName] => Persson, Tess T [FirstName] => Tess T [LastName] => Persson [StreetAddress] => Testgatan 1 [CoAddress] => c/o Eriksson, Erik [PostalCode] => 99999 [City] => Stan [CountryCode] => SE [IsGeneric] => [AddressLines] => Array ( ) ) [BillingAddress] => Array ( [FullName] => Persson, Tess T [FirstName] => Tess T [LastName] => Persson [StreetAddress] => Testgatan 1 [CoAddress] => c/o Eriksson, Erik [PostalCode] => 99999 [City] => Stan [CountryCode] => SE [IsGeneric] => [AddressLines] => Array ( ) ) [Gui] => Array ( [Layout] => desktop [Snippet] => <iframe src=\"\"></iframe> ) [Locale] => sv-SE [Currency] => SEK [CountryCode] => SE [PresetValues] => [ClientOrderNumber] => 8828014 [OrderId] => 251147 [EmailAddress] => test@yourdomain.se [PhoneNumber] => 12312313 [PaymentType] => INVOICE [Status] => Final [CustomerReference] => [SveaWillBuyOrder] => 1 [IdentityFlags] => [MerchantData] => test [Recurring] => 1 [RecurringToken] => 12345678-90ab-cdef-1234-567890abcdef (Only available when the order is FINAL) )
Checkout GUI 包含 Snippet 和 Layout。Snippet 包含您在页面上实现以显示 Svea Checkout 中 iframe 的 Html 和 JavaScript。Layout 是一个定义客户屏幕方向的字符串。
echo $response['Gui']['Snippet']
9. 其他请求
9.1 GetAvailablePartPaymentCampaigns
GetAvailablePartPaymentCampaigns 可以用于获取商家上所有可用的活动的详细信息
这些信息可用于例如在产品页面上显示有关支付特定产品或产品的费用的信息。
示例请求
$checkoutMerchantId = 100002; $checkoutSecret = "3862e010913d7c44f104ddb4b2881f810b50d5385244571c3327802e241140cc692522c04aa21c942793c8a69a8e55ca7b6131d9ac2a2ae2f4f7c52634fe30d2"; $baseUrl = \Svea\Checkout\Transport\Connector::TEST_BASE_URL; $conn = \Svea\Checkout\Transport\Connector::init($checkoutMerchantId, $checkoutSecret, $baseUrl); $checkoutClient = new \Svea\Checkout\CheckoutClient($conn); $data = array( 'IsCompany' => false ); $response = $checkoutClient->getAvailablePartPaymentCampaigns($data); echo "<pre>" . print_r($response, true) . "</pre>";
执行上述代码将返回一个包含 8.11 活动代码信息 的数组。
示例响应
Array ( [0] => Array ( [CampaignCode] => 213060 [ContractLengthInMonths] => 3 [Description] => Köp nu betala om 3 månader (räntefritt) [FromAmount] => 1000 [InitialFee] => 100 [InterestRatePercent] => 0 [MonthlyAnnuityFactor] => 1 [NotificationFee] => 29 [NumberOfInterestFreeMonths] => 3 [NumberOfPaymentFreeMonths] => 3 [PaymentPlanType] => 2 [ToAmount] => 50000 ) [1] => Array ( [CampaignCode] => 410012 [ContractLengthInMonths] => 12 [Description] => Dela upp betalningen på 12 månader [FromAmount] => 100 [InitialFee] => 0 [InterestRatePercent] => 19.9 [MonthlyAnnuityFactor] => 0.092586652785396 [NotificationFee] => 29 [NumberOfInterestFreeMonths] => 0 [NumberOfPaymentFreeMonths] => 0 [PaymentPlanType] => 0 [ToAmount] => 30000 ) )
应将信息存储在数据库中以便快速访问,而不是按需发送请求。
计算公式
计算每月价格
(InitialFee + (ceil(ProductPrice * MonthlyAnnuityFactor) + NotificationFee) * ContractLengthInMonths) / ContractLengthInMonths
使用示例中第二个活动,产品价格为 1500kr,将得到:((0 + (ceil(1500 * 0.092586652785396) + 29 ) * 12) / 12) = ((0 + (139 + 29) * 12 ) / 12) = 168kr
计算总支付金额
InitialFee + (ProductPrice * MonthlyAnnuityFactor + NotificationFee) * ContractLengthInMonths
使用示例中第二个活动,产品价格为 150kr,将得到:(0 + (150 * 0.092586652785396 + 29 ) * 12) = 514.655975 四舍五入到最接近的整数 -> 515kr
!!! 注意 !!!
如果您是芬兰商家,您必须显示此处描述的所有值 这里 以符合芬兰法律。
10. 数据结构
10.1 商家设置
10.2 项目
10.3 订单行
10.4 预设值
预设值类型名称列表
10.5 Gui
10.6 客户
10.7 地址
10.8 CheckoutOrderStatus
只有在CheckoutOrderStatus为最终状态时,订单才能被认为是“准备好发送给客户”。其他状态不能保证付款。
10.9 地域
10.10 付款类型
直接银行
10.11 营销代码信息
10.12 身份标识
10.13 Checkout验证回调响应
如果在创建订单时设置了CheckoutValidationCallbackUri,当客户点击“确认订单”时,Svea会将HTTP GET请求发送到指定的URI。
响应应具有HTTP状态200,表示请求成功。响应应包含以下所需参数。在响应之前以JSON格式编码响应。
11. HttpStatusCodes
如果返回的ResultCode不在上述表中,请联系Svea Ekonomi获取更多信息。
12. 订单管理
错误
如果任何操作失败或发生其他错误,库将抛出异常
可能的异常 \Svea\Checkout\Exception\SveaInputValidationException - 如果任何输入字段无效或缺失。
\Svea\Checkout\Exception\SveaApiException - 如果API连接出现问题或API端数据验证发生错误。
\Svea\Checkout\Exception\SveaConnectorException - 如果缺少某些字段(如merchantId、sharedSecret或baseUrl)。
\Exception - 对于任何其他错误
12.1 获取订单
此方法用于获取包含所有相关信息的整个订单。包括其配送、行、信用和地址。
参数
响应
12.2 获取任务
任务将解释先前执行的操作的状态。完成后,它将指向带有Location的新资源。
参数
响应
12.3 配送订单
在结账订单上创建配送。假设订单获得了CanDeliverOrder操作。
配送调用应包含应配送的所有订单行ID列表。如果应完成所有行的完整配送,则列表应包含所有订单行ID或为空。但是,如果指定了所有活跃订单行的一个子集,则将进行部分配送。部分配送只能在订单具有CanDeliverOrderPartially操作且每个订单行都必须具有CanDeliverRow操作的情况下进行。
响应
12.3.1 行配送选项
12.4 以较低金额配送订单
在结账订单上创建一个低于总额的配送,取消剩余金额。假设订单获得了CanDeliverOrder和CanCancelAmount操作。
当配送完成但不应捕获全额时,应使用带有较低金额的配送调用。所有订单行都将被视为已配送。
响应
12.5 取消订单
在订单配送之前取消订单。假设订单具有CanCancelOrder操作。
响应
如果订单成功取消,则响应为空。
12.6 取消订单金额
通过指定高于当前订单取消金额的金额,则订单取消金额将增加,假设订单具有CanCancelOrderAmount操作。新CancelledAmount与旧CancelledAmount之间的差值将被取消。
新CancelledAmount不能等于或低于当前CancelledAmount或超过订单上的OrderAmount。
响应
如果订单金额成功取消,则响应为空。
12.7 取消订单行
将订单行的状态更改为已取消,假设订单具有CanCancelOrderRow操作且订单行具有CanCancelRow操作。
响应
如果订单行成功取消,则响应为空。
12.8 信用订单行
在指定的交货单上创建新的信用,并指定订单行。假设交货单具有操作CanCreditOrderRows,且指定的订单行也具有操作CanCreditRow
响应
在返回的URL中可以检查任务的进度。
12.8.1 行信用选项
12.9 信用新订单行
通过指定新的信用行,在交货单上创建一个新的信用行,假设交货单具有操作CanCreditNewRow。
响应
在返回的URL中可以检查任务的进度。
12.10 带费用的信用订单行
在指定的交货单上创建新的信用,并指定订单行。假设交货单具有操作CanCreditOrderRows,且指定的订单行也具有操作CanCreditRow。增加了添加费用到信用的能力。
响应
在返回的URL中可以检查任务的进度。
12.11 信用金额
通过指定大于当前信用金额的信用金额。正在指定的交货单上进行信用操作。信用金额不能低于当前信用金额或高于交货金额。
此方法需要在交货单上具有CanCreditAmount。
响应
如果订单金额成功信用,则响应为空。
12.12 添加订单行
此方法用于向订单添加订单行,假设订单具有操作CanAddOrderRow。如果新的订单金额将超过当前的订单金额,则将执行信用检查。
响应
在返回的URL(HeaderLocation)中可以检查任务的进度。
12.13 更新订单行
此方法用于更新订单行,假设订单具有操作"CanUpdateOrderRow"和订单行具有操作CanUpdateRow。方法将更新有效载荷中设置的的所有字段,如果字段未设置,则行将保持当前值。如果新的订单金额将超过当前的订单金额,则将执行信用检查。
响应
如果订单行成功更新,则响应为空。
12.14 替换订单行
此方法用于更新订单行,假设订单具有操作"CanUpdateOrderRow"。此方法将删除所有现有的行,并用有效载荷中设置的行替换。如果新的订单金额将超过当前的订单金额,则将执行信用检查。
响应
如果订单行成功更新,则响应为空。
12.15 数据对象
12.15.1 订单
12.15.2 交货
12.15.3 信用
12.15.4 任务
12.15.5 订单行
12.15.6 地址
12.15.7 订单状态
12.15.8 订单操作
12.15.9 交货操作
12.15.10 订单行操作
13. JavaScript API
(请注意,API仍然被认为是工作进度,可能会看到重大变化。)
API入口点
window.scoApi是API的根对象,包含所有可用的操作。
监听API准备就绪
结账在准备就绪时引发事件,可以用来安全地访问API。
示例
document.addEventListener("checkoutReady", function() { window.scoApi... // Your code here });
可用的操作
observeEvent(propertyString, handlerFunction) => function
观察客户端数据的变化,当检测到变化时调用提供的函数。
返回一个可以调用的函数来停止观察指定的属性。
以下属性目前受支持
"identity.isCompany" "identity.email" "identity.phoneNumber" "identity.companyName" "identity.firstName" "identity.lastName" "identity.streetAddress" "identity.coAddress" "identity.postalCode" "identity.city" "identity.addressLines"
示例
// Observe the city property var unsubscribe = window.scoApi.observeEvent("identity.city", function (data) { console.log("City changed to %s.", data.value); }); // Stop observing unsubscribe();
setCheckoutEnabled(value) => void
传递一个假值以禁用结账。禁用时,商家可以安全地更新购物车。完成后,调用setCheckoutEnabled(true)以重新启用结账并反映所做的更改。