You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中srmklive PayPal包出现Undefined Array key 'links'错误的解决

问题描述

我是一名开发新手,在SaaS项目中使用srmklive PayPal包实现订单创建功能。点击支付按钮时出现Undefined Array key 'links'错误,希望修复该问题以实现跳转至PayPal支付页面。曾尝试改为paypal-link,但未生效,相关代码如下:

public function onBoard(Request $request): JsonResponse
{
    $plan = Plan::with('currency')->findOrFail($request->planId);

    if ($plan->currency->currency_code != null && ! in_array(strtoupper($plan->currency->currency_code),
        getPayPalSupportedCurrencies())) {
        return $this->sendError(__('messages.placeholder.this_currency_is_not_supported'));
    }

    $data = $this->subscriptionRepository->manageSubscription($request->all());

    if (! isset($data['plan'])) { // 0 amount plan or try to switch the plan if it is in trial mode
        // returning from here if the plan is free.
        if (isset($data['status']) && $data['status'] == true) {
            return $this->sendSuccess($data['subscriptionPlan']->name.' '.__('messages.subscription_pricing_plans.has_been_subscribed'));
        } else {
            if (isset($data['status']) && $data['status'] == false) {
                return $this->sendError(__('messages.placeholder.cannot_switch_to_zero'));
            }
        }
    }

    $subscriptionsPricingPlan = $data['plan'];
    $subscription = $data['subscription'];

    $mode = getSelectedPaymentGateway('paypal_mode');
    $clientId = getSelectedPaymentGateway('paypal_client_id');
    $clientSecret = getSelectedPaymentGateway('paypal_secret');

    config([
        'paypal.mode' => $mode,
        'paypal.sandbox.client_id' => $clientId,
        'paypal.sandbox.client_secret' => $clientSecret,
        'paypal.live.client_id' => $clientId,
        'paypal.live.client_secret' => $clientSecret,
    ]);

    $provider = new PayPalClient();
    $provider->getAccessToken();

    $data = [
        'intent' => 'CAPTURE',
        'purchase_units' => [
            [
                'reference_id' => $subscription->id,
                'amount' => [
                    'value' => $data['amountToPay'],
                    'currency_code' => $subscription->plan->currency->currency_code,
                ],
            ],
        ],
        'application_context' => [
            'cancel_url' => route('paypal.failed'),
            'return_url' => route('paypal.success'),
        ],
    ];

    $order = $provider->createOrder($data);

    return response()->json(['link' => $order['links'][1]['href'], 'status' => 200]);

}
问题分析与修复方案

错误原因

出现Undefined Array key 'links'的核心问题有两个:

  1. 订单创建失败:PayPal API返回了错误信息而非正常订单结构,导致$order中没有links字段
  2. 索引依赖不稳定:直接通过固定索引[1]获取链接,忽略了links数组结构可能变化的情况

修复步骤

  1. 排查订单创建失败原因

    • 验证PayPal的client_id、client_secret是否正确,环境(沙箱/生产)是否匹配
    • 确保amount.value是字符串格式(如"10.00"),PayPal不接受纯数字类型
    • 检查currency_code是否为PayPal支持的大写格式(如USD)
  2. 健壮化链接获取逻辑
    不要依赖固定索引,通过rel字段定位支付跳转链接(PayPal返回的links中,rel="approve"的项才是支付页面链接)

  3. 添加异常捕获与变量名修复
    原代码中重复使用$data变量会覆盖之前的订阅数据,需重命名避免冲突;同时捕获API调用异常,方便排查问题

修改后的代码

public function onBoard(Request $request): JsonResponse
{
    $plan = Plan::with('currency')->findOrFail($request->planId);

    if ($plan->currency->currency_code != null && !in_array(strtoupper($plan->currency->currency_code), getPayPalSupportedCurrencies())) {
        return $this->sendError(__('messages.placeholder.this_currency_is_not_supported'));
    }

    $subscriptionData = $this->subscriptionRepository->manageSubscription($request->all());

    if (!isset($subscriptionData['plan'])) { // 0 amount plan or try to switch the plan if it is in trial mode
        // returning from here if the plan is free.
        if (isset($subscriptionData['status']) && $subscriptionData['status'] == true) {
            return $this->sendSuccess($subscriptionData['subscriptionPlan']->name.' '.__('messages.subscription_pricing_plans.has_been_subscribed'));
        } else {
            if (isset($subscriptionData['status']) && $subscriptionData['status'] == false) {
                return $this->sendError(__('messages.placeholder.cannot_switch_to_zero'));
            }
        }
    }

    $subscriptionsPricingPlan = $subscriptionData['plan'];
    $subscription = $subscriptionData['subscription'];

    $mode = getSelectedPaymentGateway('paypal_mode');
    $clientId = getSelectedPaymentGateway('paypal_client_id');
    $clientSecret = getSelectedPaymentGateway('paypal_secret');

    config([
        'paypal.mode' => $mode,
        'paypal.sandbox.client_id' => $clientId,
        'paypal.sandbox.client_secret' => $clientSecret,
        'paypal.live.client_id' => $clientId,
        'paypal.live.client_secret' => $clientSecret,
    ]);

    try {
        $provider = new PayPalClient();
        $provider->getAccessToken();

        // 确保金额为字符串格式
        $amountValue = strval($subscriptionData['amountToPay']);

        $orderData = [
            'intent' => 'CAPTURE',
            'purchase_units' => [
                [
                    'reference_id' => $subscription->id,
                    'amount' => [
                        'value' => $amountValue,
                        'currency_code' => strtoupper($subscription->plan->currency->currency_code),
                    ],
                ],
            ],
            'application_context' => [
                'cancel_url' => route('paypal.failed'),
                'return_url' => route('paypal.success'),
            ],
        ];

        $order = $provider->createOrder($orderData);

        // 检查订单是否包含有效links
        if (!isset($order['links']) || empty($order['links'])) {
            return $this->sendError(__('messages.placeholder.paypal_order_create_failed'));
        }

        // 查找支付跳转链接
        $approveLink = null;
        foreach ($order['links'] as $link) {
            if ($link['rel'] === 'approve') {
                $approveLink = $link['href'];
                break;
            }
        }

        if (!$approveLink) {
            return $this->sendError(__('messages.placeholder.paypal_approve_link_not_found'));
        }

        return response()->json(['link' => $approveLink, 'status' => 200]);
    } catch (\Exception $e) {
        \Log::error('PayPal订单创建失败: '.$e->getMessage());
        return $this->sendError(__('messages.placeholder.paypal_order_create_failed').': '.$e->getMessage());
    }
}

内容的提问来源于stack exchange,提问作者Komal Shree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:05:26