pckg / payment
实现了 braintree、paypal、ideal 等支付库的完整实现
dev-next-8.0
2022-04-22 19:35 UTC
Requires
- ext-json: *
- ampeco/omnipay-bankart: dev-master
- braintree/braintree_php: 3.*
- eoler/omnipay-corvuspay: *
- icepay/api: ^0.0.1
- mollie/mollie-api-php: ^2.0
- paymill/paymill: 4.*
- paypal/rest-api-sdk-php: 1.*
- stripe/stripe-php: 7.*
- wirecard/payment-sdk-php: dev-patch-php-8 as dev-master
Requires (Dev)
- nesbot/carbon: 2.*
- pckg-app/frontend-dev: dev-next-8.0 as dev-master
- pckg/auth: dev-next-8.0 as dev-master
- pckg/collection: dev-next-8.0 as dev-master
- pckg/database: dev-next-8.0 as dev-master
- pckg/framework: dev-next-8.0 as dev-master
- pckg/generic: dev-next-8.0 as dev-master
- pckg/htmlbuilder: dev-next-8.0 as dev-master
This package is auto-updated.
Last update: 2024-09-15 20:00:14 UTC
README
项目为支付提供者提供抽象实现
- paypal(经典 API,REST API)
- paymill(信用卡,SEPA,paypal)
- icepay(信用卡,bancontact,eps,giropay,ideal,sofort)
- braintree
- axcess
- valu
- 预付款 / UPN
目前正在等待实现
- paywiser
- activa
- megapos
安装
您可以通过 composer 安装此包。
$ composer require schtr4jh/payment
Paymill
信用卡
'enabled' => true, 'private_key' => env('PAYMILL_PRIVATE_KEY'), 'public_key' => env('PAYMILL_PUBLIC_KEY'),
paypal
'enabled' => true, 'private_key' => env('PAYMILL_PRIVATE_KEY'), 'public_key' => env('PAYMILL_PUBLIC_KEY'), 'url_return' => 'payment.success', 'url_cancel' => 'payment.error',
SEPA
'enabled' => true, 'private_key' => env('PAYMILL_PRIVATE_KEY'), 'public_key' => env('PAYMILL_PUBLIC_KEY'),
paypal
经典 API
'enabled' => true, 'username' => 'schtr4jh-facilitator_api1.schtr4jh.net', 'password' => '1390585136', 'signature' => 'AOZR6pqlRlwo0Ex9.oQbP2uvOalsAHQdlhdfczB0.B699lqJXv8pigFj', 'url' => 'https://api-3t.sandbox.paypal.com/nvp', 'url_token' => 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=[token]', 'url_return' => 'payment.success', 'url_cancel' => 'payment.error',
REST API
'enabled' => false, 'id' => 'AYlzupNqmg7177ZI57MfI26mgkzN-n8QQewuicaHmi7OOEf5LNy5FIi7ooFIbwo-t9_LQR9NOqtLslF_', 'secret' => 'ECQLZ6zyH8b6JgG3hGN8Qg1u6ezDiT0HpfCK7MnKcQyyQoYtghnAndYJLu5p1g0UJmLMj7_IV1Qdbsv3', 'mode' => 'sandbox', 'url_return' => 'payment.success', 'url_cancel' => 'payment.error', 'log' => [ 'enabled' => true, 'level' => 'DEBUG', // 'FINE' for production ],
预付款
配置
'enabled' => false, 'url_waiting' => 'payment.waiting',
实现
每个项目都需要实现 \Pckg\Payment\Adapter\Order|Product|Customer|Log|Environment(称为 ProjectOrder、ProjectProduct、ProjectCustomer 和 ProductLog),它提供适当的映射器。在 Laravel 项目中使用时,您可以直接使用 Pckg\Payment\Service\LaravelPayment trait,该 trait 创建一个带有 Laravel 环境的支付服务,用于处理请求、响应、URL 生成和重定向。在其他项目中,只需实现 Payment\Adapter\Environment。
路由
// list payments 'payment' => route('PaymentController@payment', 'payment/{listing}', 'GET'), // apply promo code 'payment.promo' => route('PaymentController@promo', 'payment/{handler}/{listing}/promo', 'POST'), // validate payment request 'payment.validate' => route('PaymentController@validate', 'payment/{handler}/{listing}/validate', 'POST'), // start payment process 'payment.start' => route('PaymentController@start', 'payment/{handler}/{listing}/start', 'POST|GET'), // payment valid 'payment.success' => route('PaymentController@success', 'payment/{handler}/{listing}/success', 'GET'), // payment invalid 'payment.error' => route('PaymentController@error', 'payment/{handler}/{listing}/error', 'GET'), // payment not processed yet 'payment.waiting' => route('PaymentController@waiting', 'payment/{handler}/{listing}/waiting', 'GET'),
控制器
完整的 Laravel 实现示例
<?php namespace Net\Http; use Illuminate\Http\Request; use Net\Http\Payment\ZoneLog; use Net\Http\Payment\ZoneOrder; use Net\Http\Requests\PromoCodeRequest; use Pckg\Payment\Service\LaravelPayment; use Zone\Content\SelectItem; use Zone\Listing\Listing; use Zone\Listing\PaymentMethod; use Zone\Listing\PromoCode; class PaymentController extends BaseController { use LaravelPayment; protected $paymentService; public function __construct() { $this->paymentService = $this->createPaymentService(); } private function preparePaymentService($handler, Listing $listing) { $listing->abortIfNotMine(); $this->paymentService->prepare(new ZoneOrder($listing), $handler, new ZoneLog($listing)); } public function getPayment(Listing $listing) { $listing->abortIfNotMine(); $this->paymentService->setOrder(new ZoneOrder($listing)); $this->vendorAsset('schtr4jh/payment/src/Pckg/Payment/public/payment.js', 'footer'); return view('payment.index', [ 'listing' => $listing, 'paymentMethods' => PaymentMethod::where('enabled', 1)->get(), 'paymentService' => $this->paymentService, 'expYears' => range(date('Y') + 0, date('Y') + 16), 'expMonths' => SelectItem::cardExpirationMonths()->get(), ]); } public function postStart($handler, Listing $listing) { $this->preparePaymentService($handler, $listing); $success = $this->paymentService->getHandler()->start(); return [ 'success' => true, 'modal' => $success ? '#dialog-payment-success' : '#dialog-payment-error', ]; } public function getStart($handler, Listing $listing) { return $this->getStatus($handler, $listing, 'start'); } public function getSuccess($handler, Listing $listing) { return $this->getStatus($handler, $listing, 'success'); } public function getError($handler, Listing $listing) { return $this->getStatus($handler, $listing, 'error'); } public function getWaiting($handler, Listing $listing) { return $this->getStatus($handler, $listing, 'waiting'); } public function postValidate($handler, Listing $listing, Request $request) { $this->preparePaymentService($handler, $listing); return $this->paymentService->getHandler()->validate($request); } public function postPromo($handler, Listing $listing, PromoCodeRequest $request) { $this->preparePaymentService($handler, $listing); $canApply = false; $code = PromoCode::where('code', $request->promo_code)->first(); if ($code && (($code->discount_value && $code->discount_value < $this->paymentService->getTotal()) || $code->discount_percentage)) { $listing->forceFill([ 'promo_code_id' => $code->id, ])->save(); $canApply = true; } else { $listing->forceFill([ 'promo_code_id' => null, ])->save(); } return [ 'success' => true, 'promo_notice' => $request->promo_code ? ($canApply ? trans( 'payment.label.promo_code_valid', ['discount' => $listing->promoCode->getDiscount($this->paymentService->getCurrency())] ) : trans('payment.label.promo_code_invalid') ) : '', 'new_handler_price' => $this->paymentService->getHandler()->getTotalToPay(), 'new_button' => trans('payment.paymill.btn.pay') . ' ' . $this->paymentService->getTotalToPayWithCurrency(), ]; } protected function getStatus($handler, Listing $listing, $action) { $this->preparePaymentService($handler, $listing); $this->paymentService->getHandler()->{$action}(); return view('payment.' . $action, [ 'listing' => $listing, ]); } }