ThinkPHP接入PayPal支付

ThinkPHP 5接入PayPal 支付,PayPal的流程是服务器请求Paypal的接口下单(需要传订单id/支付成功的重定向地址/支付失败的重定向地址),接会返回一个支付地址,项目服务器把地址返给用户,用户打开链接登录Paypal完成付款,然后Paypal给重定向到指定地址。

在paypal官网开通商户号,设置通知地址。

开通沙箱模式用于测试,后台会给沙箱模式生成商户账号和用户账号,请注意区分。

申请和开通网上有教程不在赘述。

具体实现步骤如下

1.安装包

composer require paypal/rest-api-sdk-php:*

2.具体实现代码

<?phpnamespace app\api\controller;use app\common\controller\Api;
use app\common\model\ShopOrder;
use PayPal\Api\Amount;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\Transaction;
use PayPal\Api\PaymentExecution;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Rest\ApiContext;
use PayPal\Api\RedirectUrls;
use think\Log;
class Paypal extends Api
{protected $noNeedLogin = ['*'];protected $noNeedRight = ['*'];private $apiContext;public function __construct(){parent::__construct();// 初始化PayPal API上下文$this->apiContext = new ApiContext(new OAuthTokenCredential('AV8d**************************N-jbpRvV-K0_dLuEA5d8uodUowab6jdWtM',     // 客户端ID'EByrRAncAi*****************************RSqIRA'         // 客户端密钥));$this->apiContext->setConfig(['mode' => 'sandbox',      // 或者 'live'// 其他配置...]);}/*** 下单接口* @return \think\response\Json|void* @throws \think\db\exception\DataNotFoundException* @throws \think\db\exception\ModelNotFoundException* @throws \think\exception\DbException*/public function createPaypalPaymentUrl(){// 获取前端传递的order_Id$orderId = input('post.order_id');// 查询订单信息(这里你需要根据自己的数据库结构进行查询)// 假设我们得到了一个包含订单详情的数组$orderInfo$orderInfo = ShopOrder::where('id', $orderId)->where('status', '1')->find();if (empty($orderInfo)) {$this->error('订单不存在或不是待支付状态');}// 设置Payer信息,表明付款人是通过PayPal付款$payer = new Payer();$payer->setPaymentMethod("paypal");// 设置交易金额$amount = new Amount();$amount->setCurrency("AUD")->setTotal(number_format($orderInfo['actual_money'], 2, '.', ''));// 创建Transaction对象,并使用订单ID作为发票号$transaction = new Transaction();$transaction->setAmount($amount)->setDescription("Slem order pay")  // 描述可选->setInvoiceNumber($orderInfo->order_num);  // 使用订单order_num作为发票号// 创建RedirectUrls对象$redirectUrls = new RedirectUrls();$redirectUrls->setReturnUrl("https://*******.cn/api/paypal/paymentSuccess")  // 支付成功后的回调地址->setCancelUrl("https://********/api/paypal/paymentCancel");  // 用户取消支付后的回调地址// 创建Payment对象$payment = new Payment();$payment->setIntent("sale")->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions([$transaction]);try {// 创建支付请求$payment->create($this->apiContext);// 获取approval_url,这是用户需要访问来完成支付的URLforeach ($payment->getLinks() as $link) {if ($link->getRel() == 'approval_url') {// 返回支付链接给客户端return json(['code' => 1, 'data' => $link->getHref()]);
//                    $data = ['status' => 'success', 'approval_url' => $link->getHref()];
//                    $this->success(__('SUccess'),$data);}}} catch (\Exception $ex) {// 输出详细的错误信息return json(['status' => 'error','message' => 'Error creating PayPal payment: ' . $ex->getMessage(),'details' => $ex->getTraceAsString(),'response' => $payment->toArray()]);}}/*** 支付成功跳转的页面* 建议前端出个html后台做渲染,本方法只为展示流程* @return \think\response\Json*/public function paymentSuccess(){// 获取PayPal传递过来的参数$paymentId = input('get.paymentId');$payerId = input('get.PayerID');if (empty($paymentId) || empty($payerId)) {return json(['status' => 'error', 'message' => 'Missing payment ID or payer ID']);}try {// 获取支付信息$payment = Payment::get($paymentId, $this->apiContext);// 创建PaymentExecution对象并设置payer_id$execution = new PaymentExecution();$execution->setPayerId($payerId);// 执行支付请求$result = $payment->execute($execution, $this->apiContext);// 检查支付状态if ($result->getState() === 'approved') {// 使用发票号(即订单ID)来查找订单$invoiceNumber = $payment->getTransactions()[0]->getInvoiceNumber();$order = ShopOrder::where('order_num', $invoiceNumber)->find();if (!empty($order)) {// 更新订单状态为已支付$order->payment = 'paypal';$order->status = '2';$order->save();// 你可以在这里添加更多的业务逻辑,比如发送确认邮件等// 返回成功信息给前端return json(['status' => 'success', 'message' => 'Payment successful']);} else {return json(['status' => 'error', 'message' => 'Order not found']);}} else {return json(['status' => 'error', 'message' => 'Payment not approved']);}} catch (\Exception $ex) {// 错误处理Log::error('PayPal Error: ' . $ex->getMessage());return json(['status' => 'error','message' => 'Error executing payment: ' . $ex->getMessage(),'details' => $ex->getTraceAsString()]);}}/*** 支付取消跳转的页面* @return \think\response\Json*/public function paymentCancel(){// 获取订单ID或其他相关信息(如果需要)$orderId = input('get.order_id'); // 如果PayPal回调包含order_idif (!empty($orderId)) {try {// 根据订单ID查找订单信息$order = ShopOrder::where('id', $orderId)->find();if (!empty($order)) {// 你可以在这里添加更多的业务逻辑,比如记录取消原因、发送通知等// 更新订单状态为已取消或保持不变,视业务需求而定// 这里假设我们不改变订单状态,仅记录取消事件Log::info("Payment cancelled for order ID: " . $orderId);// 返回取消信息给前端return json(['status' => 'info', 'message' => 'Payment cancelled.']);} else {return json(['status' => 'error', 'message' => 'Order not found.']);}} catch (\Exception $ex) {// 错误处理Log::error('Error handling payment cancellation: ' . $ex->getMessage());return json(['status' => 'error','message' => 'An error occurred while processing your request.','details' => $ex->getTraceAsString()]);}} else {// 如果没有提供订单ID,则简单地告知用户支付已被取消return json(['status' => 'info', 'message' => 'Payment cancelled.']);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64080.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html + css 淘宝网实战

之前有小伙伴说&#xff0c;淘宝那么牛逼你会写代码&#xff0c;能帮我做一个一样的淘宝网站吗&#xff0c;好呀&#xff0c;看我接下来如何给你做一个淘宝首页。hahh,开个玩笑。。。学习而已。 在进行html css编写之前 先了解下网页的组成和网页元素的尺寸吧 1.网页的组成 …

【不太正常的题】LeetCode.232:用栈的函数接口实现队列

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;初阶数据结构刷题 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f697; 1.问题描述&#xff1a; 题目中说了只能使用两个栈实现队列&#xff0c;并且只能使用…

Linux搭建text-generation-webui框架,安装通义千问大模型,开放对外api,voxta测试对话图文教程

目录 text-generation-webui部分 开放对外API 通义千问部分 远程API对话测试部分 text-generation-webui部分 本来不想发这个文章的&#xff0c;但是自己部署的时候看了挺多人的帖子&#xff0c;很多发的不全面&#xff0c;要么就是跟着他们流程走有些小问题啥的&#xff…

QT程序发布后,mysql在其它电脑设备无法连接数据库

QT程序发布后&#xff0c;mysql在其它电脑设备无法连接数据库 D:\mysql-5.7.24-winx64\lib, mysql-5.7.24-winx64是一个压缩包&#xff0c;用于启动mysql服务&#xff0c;创建数据库 压缩包 解决方法&#xff1a; 拷贝库到exe的相同目录&#xff0c;libmysql.dll,libmysql.li…

Nginx单向链表 ngx_list_t

目录 基本概述 数据结构 接口描述 具体实现 ngx_list_create ngx_list_init ngx_list_push 使用案例 整理自 nginx 1.9.2 源码 和 《深入理解 Nginx&#xff1a;模块开发与架构解析》 基本概述 Nginx 中的 ngx_list_t 是一个单向链表容器&#xff0c;链表中的每一个节…

软件项目需求分析的实践探索(1)

一、项目启动与规划 组建团队 包括项目经理、系统分析师、业务分析师以及可能涉及的最终用户代表和领域专家等。例如&#xff0c;开发一个医疗管理软件&#xff0c;就需要有医疗行业的专家参与&#xff0c;确保对医疗业务流程有深入理解。明确各成员的职责&#xff0c;如系统分…

网络管理-期末项目(附源码)

环境&#xff1a;网络管理 主机资源监控系统项目搭建 &#xff08;保姆级教程 建议点赞 收藏&#xff09;_搭建网络版信息管理系统-CSDN博客 效果图 下面3个文件的项目目录(python3.8.8的虚拟环境) D:\py_siqintu\myproject5\Scripts\mytest.py D:\py_siqintu\myproject5\Sc…

MySQL 常用程序介绍

以下是一些常用的MySQL程序&#xff1a; 程序名作⽤mysqldMySQL的守护进程即 MySQL 服务器&#xff0c;要使⽤MySQL 服务器 mysqld必须正在运⾏状态mysql MySQL客⼾端程序&#xff0c;⽤于交互式输⼊ SQL 语句或以批处理模式从⽂件执⾏SQL的命令⾏⼯具 mysqlcheck⽤于检查、修…

Redis篇--常见问题篇4--大Key(Big Key,什么是大Key,影响及使用建议)

1、概述 大Key&#xff1a;通常是指值&#xff08;Value&#xff09;的长度非常大&#xff0c;实际上键&#xff08;Key&#xff09;长度很大也算。通常来说&#xff0c;键本身不会很长&#xff0c;占用的内存较少&#xff0c;因此判断一个键是否为bigKey主要看它对应的值的大…

ModbusTCP从站转Profinet主站案例

一. 案例背景 在复杂的工业自动化场景中&#xff0c;企业常常会采用不同品牌的设备来构建生产系统。西门子SINAMICS G120变频器以其高性能、高精度的速度和转矩控制功能&#xff0c;在电机驱动领域应用广泛。施耐德M580可编程逻辑控制器则以强大的逻辑控制和数据处理能力著称&…

微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择

Area 省市区选择&#xff0c;省市区选择组件通常与 弹出层 组件配合使用。 areaList 格式 areaList 为对象结构&#xff0c;包含 province_list、city_list、county_list 三个 key。 每项以地区码作为 key&#xff0c;省市区名字作为 value。地区码为 6 位数字&#xff0c;前两…

智驾感知「大破局」!新一轮混战开启

随着智能驾驶搭载率的攀升&#xff0c;舱外传感器赛道迎来新变局。 一方面&#xff0c;从近几年智驾传感器的配置变化来看&#xff0c;摄像头的主导地位显而易见。 12月10-12日&#xff0c;由德赛西威总冠名的2024&#xff08;第八届&#xff09;高工智能汽车年会暨年度金球奖…

Kibana8.17.0在mac上的安装

1、Kibana是什么 Kibana是与elasticsearch配套使用的数据分析与可视化工具&#xff0c;通过Kibana可以轻松与es中存储的数据进行高效的交互&#xff0c;包括数据写入、检索、删除等操作&#xff0c;并可以通过编写部分代码将数据做成各种报表&#xff0c;从而进行非常直观的统…

数字IC后端设计实现十大精华主题分享

今天小编给大家分享下吾爱IC社区星球上周十大后端精华主题。 Q1:星主&#xff0c;请教个问题&#xff0c;长tree的时候发现这个scan的tree 的skew差不多400p&#xff0c;我高亮了整个tree的schematic&#xff0c;我在想是不是我在这一系列mux前边打断&#xff0c;设置ignore p…

给bmp和png,设置BLENDFUNCTION的AlphaFormat不同参数的效果

BLENDFUNCTION是AlphaBlend用控制透明效果的重要参数。 选择一个32位的png图片&#xff0c;设置AlphaFormat 为 AC_SRC_ALPHA&#xff0c;效果如上图。 选择一个32位的png图片&#xff0c;设置AlphaFormat 为 0&#xff0c;效果如上图。 选择一个24位的bmp图片&#xff0c;设置…

ChildLife“童年时光杯”足球联赛启动 共促青少年健康成长

2024年12月21日至22日&#xff0c;由美国知名婴幼儿营养品牌ChildLife童年时光赞助的“童年时光杯”青少年足球联赛将在上海拉开帷幕。本次赛事U7/U8组别共有16支足球队参赛&#xff0c;包括上海幸运星足球俱乐部旗下的明星球队&#xff0c;以及其他青少年俱乐部的优秀队伍&…

MTK--mt7921 usb wifi debug

文章目录 1、代码编译2、配置文件修改3、Wifi设置命令4、Wifi debug 淘宝随便买个7921的usb wifi。 1、代码编译 export TEMPLATECONF${PWD}/meta/meta-mediatek-mt8518/conf/base/aud8518sp2-slc-32b-7921-c4a-user source meta/poky/oe-init-build-env bitbake mtk-image-au…

如何配置OSB连接数据连接/读取超时

1.Oracle DB OSB中的DBAdapter的查询超时参数配置没用&#xff0c;要解决接口超时问题&#xff0c;需要在console中的数据源配置超时参数&#xff1a; oracle.net.CONNECT_TIMEOUT30000 oracle.net.READ_TIMEOUT30000 添加图片注释&#xff0c;不超过 140 字&#xff08;可选…

一起学Git【第六节:查看版本差异】

git diff是 Git 版本控制系统中用于展示差异的强大工具。他可以用于查看文件在工作区、暂存区和版本库之间的差异、任意两个指定版本之间的差异和两个分支之间的差异等,接下来进行详细的介绍。 1.显示工作区与暂存区之间的差异 # 显示工作区和暂存区之间的差异,后面不加参数…

Python数据处理——re库与pydantic的使用总结与实战,处理采集到的思科ASA防火墙设备信息

目录 Python正则表达式re库的基本用法 引入re库 各函数功能 总结 使用方法举例 正则表达式语法与书写方式 正则表达式的常用操作符 思科ASA防火墙数据 数据1 数据2 书写正则表达式 Python中pydantic的使用 导入基础数据模板 根据数据采集目标定义Pydantic数据类型…