PHP项目如何集成支付功能?

wen java案例 3

本文目录导读:

PHP项目如何集成支付功能?

  1. 阶段一:准备工作(必做)
  2. 阶段二:核心代码实现(以支付宝当面付和微信支付的JSAPI为例)
  3. 阶段三:安全性关键点(必读)
  4. 实战建议(减少踩坑)

在 PHP 项目中集成支付功能,通常不是直接操作支付接口的底层协议(如 TCP),而是通过接入支付服务商提供的开放 API(如支付宝、微信支付、PayPal 等)来实现。

核心流程可以简化为:用户发起支付 -> 你后端生成订单并请求支付平台 -> 用户跳转支付或扫码 -> 支付平台异步通知你 -> 你更新订单状态

下面是具体、实用的集成步骤,分阶段讲解:

准备工作(必做)

  1. 选择支付渠道

    • 国内:支付宝、微信支付(最常见)。
    • 国外:PayPal、Stripe。
    • 聚合支付:选择如 Laravel Cashier(团队维护)、OmnipayPay 等第三方包,可以一套代码对接多种支付。
  2. 获取商户资质

    • 注册成为开发者/商户。
    • 获得 商户号(MCH ID)
    • 下载并配置 密钥(API Key / App Secret)证书文件(如需,如微信支付退款需要)
    • 设置 回调地址(Notify URL):这是你服务器接收支付结果的接口。
  3. 搭建开发环境

    • 确保服务器支持 HTTPS(支付宝、微信强制要求在生产环境回调时使用 HTTPS)。
    • 安装 PHP 扩展(如 curlopenssljson)。

核心代码实现(以支付宝当面付和微信支付的JSAPI为例)

推荐方案:使用 Composer 包管理。 不要自己从头编写签名、XML解析等代码。

方案 A:使用支付宝官方 PHP SDK(推荐)

composer require alipay/alipay-sdk-php
  1. 配置:创建配置文件 alipay_config.php,包含 app_idmerchant_private_key(应用私钥)、alipay_public_key(支付宝公钥)、notify_urlreturn_url

  2. 发起支付(以手机网站支付为例)

    <?php
    require_once 'vendor/autoload.php';
    require_once 'config/alipay_config.php'; // 引入配置
    use Alipay\EasySDK\Kernel\Factory;
    // 1. 初始化SDK
    Factory::setOptions($config); // $config 从 alipay_config.php 获取
    // 2. 构建请求参数
    $order = [
        'out_trade_no' => time() . rand(1000,9999), // 商户订单号
        'total_amount' => '0.01', // 金额,单位元
        'subject'      => '测试商品',
        'product_code' => 'QUICK_WAP_WAY',
    ];
    // 3. 调用SDK发起支付
    $result = Factory::payment()->wap()->pay(
        $order['subject'],
        $order['out_trade_no'],
        $order['total_amount'],
        $order['product_code']
    );
    // 4. 返回HTML页面(自动跳转到支付宝收银台)
    echo $result->body; // 实际上是一个自动提交的表单
  3. 处理异步通知(Notifiy URL)

    <?php
    require_once 'vendor/autoload.php';
    use Alipay\EasySDK\Kernel\Factory;
    // 1. 验证签名
    $result = Factory::payment()->common()->verifyNotify($_POST); // $_POST 是支付宝POST过来的数据
    if ($result === true) { // 签名通过
        // 2. 获取订单号,检查金额,防止篡改
        $out_trade_no = $_POST['out_trade_no'];
        $trade_no = $_POST['trade_no']; // 支付宝交易号
        $total_amount = $_POST['total_amount'];
        // 3. 业务逻辑:查询本地订单,核对金额,更新状态为“已支付”
        // if (signature valid && amount matches) {
        //    $order->status = 'paid';
        // }
        // 4. 必须返回 "success" (全小写)给支付宝,否则会重复通知
        echo 'success';
    } else {
        echo 'fail';
    }

方案 B:使用微信支付 PHP SDK(推荐 wechatpay/wechatpay

composer require wechatpay/wechatpay
  1. 配置:获取 mchid(商户号)、apiclient_key.pem(商户私钥文件)、wechatpay-cert.pem(平台证书公钥文件)。

  2. 支付(以JSAPI为例, 需获取用户的openid)

    <?php
    use WeChatPay\Builder;
    use WeChatPay\Crypto\Rsa;
    use WeChatPay\Formatter;
    $instance = Builder::factory([
        'mchid' => '你的商户号',
        'serial' => '商户证书序列号',
        'privateKey' => file_get_contents('/path/to/apiclient_key.pem'),
        'certs' => ['平台证书序列号' => file_get_contents('/path/to/wechatpay-cert.pem')],
    ]);
    // 构建 prepay_id 请求
    $resp = $instance->chain('v3/pay/transactions/jsapi')->post([
        'json' => [
            'appid' => '你的小程序/公众号APPID',
            'mchid' => '你的商户号',
            'description' => '测试商品',
            'out_trade_no' => time() . rand(1000,9999),
            'notify_url' => 'https://你的域名/wechat_notify.php',
            'amount' => ['total' => 1, 'currency' => 'CNY'], // 单位:分
            'payer' => ['openid' => '用户openid'],
        ],
    ]);
    $prepay_id = $resp['prepay_id'];
    // 将 prepay_id 传递给前端,由前端调用微信JS-SDK唤起支付
  3. 处理异步通知

    • 需要验证签名(使用微信支付平台证书公钥)。
    • 解密回调数据中的 resource 字段(AES-256-GCM 加密)。
    • 同样,最终需返回 XML 格式的 SUCCESSFAIL

安全性关键点(必读)

即使完成了接口对接,以下安全措施也必须实施:

  1. 验证签名(Sign)所有回调都必须验证签名,支付宝使用 RSA2(推荐),微信使用平台证书公钥验证。绝对不要信任未经签名的数据。
  2. 金额校验:在异步通知的处理逻辑中,必须将接收到的支付结果中的 actual_paid_amount(实际支付金额) 与本地数据库中的订单金额进行精确比对,防止坏人伪造成功回调,把1元订单改成0.01元。
  3. 订单号防重:确保你的 out_trade_no 是唯一的,支付平台允许幂等(同一通知可能多次发送),你的业务逻辑必须处理重复通知(通过数据库主键或唯一索引防止重复更新)。
  4. 使用 HTTPS加密,防止中间人攻击。
  5. 日志记录:记录所有支付请求、成功/失败的回调数据(脱敏后),方便排查问题和进行对账。

实战建议(减少踩坑)

  • 推荐使用框架:Laravel 有官方推荐的 Laravel Cashier(支持 Stripe、Paddle、Mollie 等国际支付)或 Laravel Alipay 等第三方包,ThinkPHP 也有相应的集成包,它们封装了签名、路由、模型等,能极大降低工作量。
  • 沙箱环境测试:所有支付服务商都提供沙箱(Sandbox)环境,用沙箱账号和测试金额先跑通流程,确认回调能正常接收。
  • 杜绝硬编码app_idsecretmch_id 等敏感信息放在 .env 文件或环境变量中,不要直接写在代码里。
步骤 操作 说明
1 选择支付渠道+获取商户资质 商户号、密钥、回调地址
2 安装官方SDK(Composer) 省去签名、HTTP请求、XML/JSON编解码的麻烦
3 实现“前端/用户点击 -> 后端生成预支付单” 生成订单号,调用SDK的创建支付接口,获取支付链接/参数
4 实现“后端接收异步通知” 验证签名、核对金额、更新订单状态、返回success
5 实现“查询 & 对账” 提供订单查询、退款等能力

一句话总结:不要重复造轮子,用官方SDK;注重签名验证和金额校验;异步通知里一定要幂等处理。

抱歉,评论功能暂时关闭!