本文主要是介绍PHP 对接paypal,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
提示:以下示例为CRMEB 开发示例,TP版本可以跳过 二、三.1 三.2
文章目录
- 一、注册申请PayPal账号
- 二、安装paypal SDK
- 三、增加配置分类 (非CMEB 可跳过)
- 四、增加paypal代码
- 1.增加后台paypal 配置代码 (非CMEB 可跳过)
- 2.增加启用状态返回值 (非CMEB 可跳过)
- 3.增加支付类型和paypal支付链接返回
- 五.遇到的问题和解决方法
- 1、调用sdk 提示 swoole_curl_setopt 10083不支持
- 总结
提示:以下是本篇文章正文内容,下面案例可供参考
一、注册申请PayPal账号
首先去官网注册一个paypal账号,注册完登录后,进入开发者中心
二、安装paypal SDK
composer 怎么安装应该就不用说了吧 不会安装的可以百度一下 很多教程
composer require paypal/rest-api-sdk-php
三、增加配置分类 (非CMEB 可跳过)
1、需要在后台 “设置”->“系统维护”->“开发配置”->“配置分类”->"支付配置"中增加paypal支付配置
2、在paypal支付配置 的 配置列表中增加配置项(配置名称无所谓,变量字段需要认真设置)
四、增加paypal代码
1.增加后台paypal 配置代码 (非CMEB 可跳过)
在app/services/system/config/SteamConfigServices.php : 2082 行增加paypal支付配置代码,需要注意的是Build::input
第一个参数需要与 步骤1-2 的变量字段一致
代码如下(示例):
->option('paypal支付', [Build::alert('paypal支付(地址:https://developer.paypal.com,需要配置Webhook)', Alert::WARNING)->showIcon(true),Build::switch('paypal_status', $data['paypal_status']['info'], (int)$data['paypal_status']['value'])->control(1, [Build::input('paypal_client_id', $data['paypal_client_id']['info'], $data['paypal_client_id']['value'])->info($data['paypal_client_id']['desc']),Build::input('paypal_client_secret', $data['paypal_client_secret']['info'], $data['paypal_client_secret']['value'])->rows(5)->type('textarea')->info($data['paypal_client_secret']['desc']),Build::input('paypal_currency', $data['paypal_currency']['info'], $data['paypal_currency']['value'])->rows(5)->type('textarea')->info($data['paypal_currency']['desc']),])->trueValue('开启', 1)->falseValue('关闭', 0)->info($data['paypal_status']['desc']),
])
2.增加启用状态返回值 (非CMEB 可跳过)
订单详情接口 app/controller/api/v1/order/StoreOrderController.php detail方法
增加paypal支付状态返回值,
代码如下(示例):
$order['paypal_status'] = sys_config('paypal_status') ? 1 : 0;//paypal支付 1 开启 0 关闭
3.增加支付类型和paypal支付链接返回
订单详情接口 app/controller/api/v1/order/StoreOrderController.php pay方法
,
代码如下(示例):
public function pay(Request $request, StorePinkServices $services, OrderPayServices $payServices, YuePayServices $yuePayServices,PaypaylPayService $paypaylPayService){//******** CREMB 代码就不贴了$order['pay_type'] = $paytype; //重新支付选择支付方式switch ($order['pay_type']) {//CREMB 代码就不贴了case PayServices::PAYPAL://增加 paypal支付类型 并请求paypalPayService 获取支付链接//TODO 请求PAYPAL支付返回支付参数$pay = $paypaylPayService->pay($order->toArray());if (is_array($pay))return app('json')->status($pay['status'], $pay['msg']);elsereturn app('json')->status('paypal', ['order_id'=>$order['order_id'],'jsConfig' => $pay]);break;}}
在app/services/pay
增加 PaypaylPayService.php
文件,具体代码如下
<?php// +----------------------------------------------------------------------// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]// +----------------------------------------------------------------------// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.// +----------------------------------------------------------------------// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权// +----------------------------------------------------------------------// | Author: CRMEB Team <admin@crmeb.com>// +----------------------------------------------------------------------namespace app\services\pay;use App\Models\PaymentRecord;use App\Vendor\BLog;use Illuminate\Http\Request;use PayPal\Api\Amount;use PayPal\Api\Details;use PayPal\Api\Item;use PayPal\Api\ItemList;use PayPal\Api\Payer;use PayPal\Api\Payment;use PayPal\Api\RedirectUrls;use PayPal\Api\Refund;use PayPal\Api\Transaction;use PayPal\Api\ExecutePayment;use PayPal\Api\PaymentExecution;use PayPal\Exception\PayPalConnectionException;use PayPal\Api\Sale;use PayPal\Rest\ApiContext;use PayPal\Auth\OAuthTokenCredential;use think\exception\ValidateException;/*** paypal 支付* Class PaypaylPayService* @package app\services\pay*/class PaypaylPayService{protected $clientId;protected $clientSecret;protected $currency;protected $accept_url;protected $PayPal;public function __construct(){$this->clientId = sys_config('paypal_client_id');//'AYTs9IoyjC8F2_D8xWZdmLiNetToAPJqT_S1w6FP_FLrXGGW8nMG7HnQgaFbGXP0Tz6KcY0V-VV2tL1x';$this->clientSecret = sys_config('paypal_client_secret');//'EAx1mFZghicg5La3-yBZcpgNXgxApgPhfPzOgu6gW24o5nAnYsGPJVHtWNBCLYc9vjkYJthYRvkEor9D';$this->currency = sys_config('paypal_currency');//'USD';//币种$this->accept_url = '支付返回地址';//返回地址//初始化$this->PayPal = new ApiContext(new OAuthTokenCredential($this->clientId,$this->clientSecret));//线上使用请打开下面代码
// $this->PayPal->setConfig([
// 'mode' => 'live',
// ]);}/*** @param* $product 商品* $price 价钱* $shipping 运费* $description 描述内容*/public function pay(array $orderInfo){if(!$orderInfo) {throw new ValidateException('订单不存在');}if($orderInfo['paid']) {throw new ValidateException('该订单已支付!');}//组件订单支付数据$product = "商品订单";$description = "支付订单:{$orderInfo['order_id']}";$paypal = $this->PayPal;$shipping = $orderInfo['pay_postage'];//运费$price = $orderInfo['pay_price'] - $shipping;//商品价格$total = $orderInfo['pay_price'];//总价$payer = new Payer();$payer->setPaymentMethod('paypal');//设置产品数据$item = new Item();$item->setName($product)->setCurrency($this->currency)->setQuantity(1)->setPrice($price);$itemList = new ItemList();$itemList->setItems([$item]);//设置订单数据$details = new Details();$details->setShipping($shipping)->setSubtotal($price);$amount = new Amount();$amount->setCurrency($this->currency)->setTotal($total)->setDetails($details);$transaction = new Transaction();$transaction->setAmount($amount)->setItemList($itemList)->setDescription($description)->setInvoiceNumber($orderInfo['order_id']);$redirectUrls = new RedirectUrls();$redirectUrls->setReturnUrl($this->accept_url . "?success=true&orderId={$orderInfo['order_id']}")->setCancelUrl($this->accept_url. "/?success=false&orderId={$orderInfo['order_id']}");$payment = new Payment();$payment->setIntent('sale')->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions([$transaction]);try {$payment->create($paypal);} catch (PayPalConnectionException $e) {throw new ValidateException($e->getMessage());}$approvalUrl = $payment->getApprovalLink();return $approvalUrl;}/*** 回调* @param Request $request* @return void*/public function paypal_recharge() {//所有log 都是记录 回调数据 失败啊 成功啊 写接口调用此方法就行 但是要把get传参改掉 从接口获取get 然后传给此方法\think\facade\Log::info('paypal支付回调,数据:'.json_encode($_GET) );$tPaymentRecordId = trim($_GET['paymemtRecordID']);$appOrderNO = trim($_GET['orderId']);//业务逻辑,查询订单表$success = trim($_GET['success']);if ($success == 'false' && !isset($_GET['paymentId']) && !isset($_GET['PayerID'])) {\think\facade\Log::info('paypal支付取消付款,数据:'.json_encode($_GET) );return false;}$paymentId = trim($_GET['paymentId']);$PayerID = trim($_GET['PayerID']);if (!isset($success, $paymentId, $PayerID)) {\think\facade\Log::info('paypal支付失败,数据:'.json_encode($_GET) );return false;}if ((bool)$_GET['success'] === 'false') {\think\facade\Log::info('paypal支付失败,数据:'.json_encode($_GET) );return false;}$payment = Payment::get($paymentId, $this->PayPal);$execute = new PaymentExecution();$execute->setPayerId($PayerID);try {$payment->execute($execute, $this->PayPal);} catch (\Exception $e) {$log = '支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】';\think\facade\Log::info('paypal支付核验失败,数据:'.json_encode($_GET) );return false;}\think\facade\Log::info('paypal支付成功,数据:'.json_encode($_GET) );//支付成功的后续操作$pay_log = $this->Pay_log_model->get_info($tPaymentRecordId);if(!empty($pay_log)){if($pay_log['pay_status'] == 0){//修改支付状态$log_data = array('pay_status'=>1,'trade_no'=>$appOrderNO,'pay_trans_id'=>$paymentId,'pay_code'=>$success);$this->Pay_log_model->save($log_data, $tPaymentRecordId);}}return true;}}
五.遇到的问题和解决方法
1、调用sdk 提示 swoole_curl_setopt 10083不支持
订单详情接口 app/controller/api/v1/order/StoreOrderController.php detail方法
增加paypal支付状态返回值,
提示:swoole_curl_setopt():option[10083] is not supported
解决方法:
- 命令行切换php 7.4,进入终端 运行
php --ri swoole
查看 swoole 未开启 curl-native。(默认宝塔安装的都是没有开启的) - 进入软件商店 卸载 swoole 扩展
- 重新手动安装扩展 ,参考大佬的swoole安装教程
- 修改配置文件时别忘了加上 extension = swoole_loader74.so 这句
- 重启CRMEB swoole 进程
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
这篇关于PHP 对接paypal的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!