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

使用PayPal Checkout PHP SDK如何获取买家完整收货地址

PayPal Checkout 免注册买家完整收货地址获取方案

问题现象

对接PayPal Checkout PHP SDK,采用authorize授权支付模式,需要在订单完成后获取Guest免注册买家的完整收货地址入库,但调用接口查询订单详情时,$orderResponse->result->payer->address 节点仅返回country_code国家编码,即使用户在Guest银行卡支付流程中填写了完整收货信息,也无法获取其余地址字段。

相关问题代码

后端支付处理逻辑

$environment = new \PayPalCheckoutSdk\Core\SandboxEnvironment(PAYPAL_ID, PAYPAL_SECRET);
$client = new \PayPalCheckoutSdk\Core\PayPalHttpClient($environment);
$authorizationId = $_POST['authorizationId'];

$request = new \PayPalCheckoutSdk\Payments\AuthorizationsGetRequest($authorizationId);
$authorizationResponse = $client->execute($request);
$orderId = $authorizationResponse->result->supplementary_data->related_ids->order_id;

$request = new OrdersGetRequest($orderId);
$orderResponse = $client->execute($request);

var_dump($orderResponse->result->payer->address);

代码执行输出仅包含国家码:

public 'address' => 
    object(stdClass)[74]
      public 'country_code' => string 'FR' (length=2)

后端创建订单逻辑

$order = json_encode([
    'purchase_units' => [
        [
            'description' => 'some desc...',
            'items'       => array_map(function ($product) {
                return [
                    'name'        => $product['name'] . " (n°" . $product['num'] . " | " . strtoupper($product['language']) . ")",
                    'quantity'    => $_SESSION['cart'][$product['id']],
                    'unit_amount' => [
                        'value'         => number_format((float)$product['price'], 2, '.', ''),
                        'currency_code' => 'USD',
                    ]
                ];
            }, $products),
            'amount'      => [
                'currency_code' => 'USD',
                'value'         => $total > 200 ? $total : $total + 8,
                'breakdown'     => [
                    'item_total' => [
                        'currency_code' => 'USD',
                        'value'         => $total
                    ],
                    'shipping' => [
                        'currency_code' => 'USD',
                        'value'         => $total > 200 ? '0.00' : '8.00',
                    ]
                ]
            ]
        ]
    ]
]);

前端JS SDK对接逻辑

paypal.Buttons({
    createOrder: (data, actions) => {
        return actions.order.create(<?= $order; ?>);
    },
    onApprove: async (data, actions) => {
        const authorization = await actions.order.authorize()
        const authorizationId = authorization.purchase_units[0].payments.authorizations[0].id
        const response = await fetch('<?= base_url('cart/process'); ?>', {
            method: 'post',
            headers: {
                'content-type': 'application/json'
            },
            body: JSON.stringify({
                authorizationId
            })
        })
        let responseText = await response.text();
        $('.site-content').html(responseText);
    },
    onCancel: function(data, actions) {
        alert("Order cancelled successfully!");
    },
    onError: function(err) {
        console.log(err);
    }
}).render('#paypal-button-container');

问题原因

  • 字段读取位置错误:payer->address节点仅存储付款人账号关联的基础国家信息,完整收货地址不在这个节点下。
  • 订单创建参数缺失:创建订单时没有显式声明收货地址收集规则,PayPal默认不会向商家返回Guest用户填写的完整收货明细。
  • 后端参数接收逻辑有问题:前端传参使用application/json格式,PHP原生$_POST无法直接获取JSON请求体内容,会导致参数读取异常。

修复步骤

  • 第一步:调整订单创建参数,添加application_context配置明确收货地址收集规则。
$order = json_encode([
    // 新增上下文配置,声明地址收集规则
    'application_context' => [
        // 本站未提前收集地址选GET_FROM_FILE,由PayPal负责引导用户填写地址
        // 本站已收集地址选SET_PROVIDED_ADDRESS,需在purchase_units下补充shipping节点传入已收集的地址供用户确认
        // 虚拟商品无物流需求选NO_SHIPPING
        'shipping_preference' => 'GET_FROM_FILE'
    ],
    'purchase_units' => [
        [
            // 原有商品、金额等配置保持不变
            'description' => 'some desc...',
            'items'       => array_map(function ($product) {
                return [
                    'name'        => $product['name'] . " (n°" . $product['num'] . " | " . strtoupper($product['language']) . ")",
                    'quantity'    => $_SESSION['cart'][$product['id']],
                    'unit_amount' => [
                        'value'         => number_format((float)$product['price'], 2, '.', ''),
                        'currency_code' => 'USD',
                    ]
                ];
            }, $products),
            'amount'      => [
                'currency_code' => 'USD',
                'value'         => $total > 200 ? $total : $total + 8,
                'breakdown'     => [
                    'item_total' => [
                        'currency_code' => 'USD',
                        'value'         => $total
                    ],
                    'shipping' => [
                        'currency_code' => 'USD',
                        'value'         => $total > 200 ? '0.00' : '8.00',
                    ]
                ]
            ]
        ]
    ]
]);
  • 第二步:修正后端支付处理逻辑,从正确节点读取收货地址,同时修复JSON参数接收问题。
$environment = new \PayPalCheckoutSdk\Core\SandboxEnvironment(PAYPAL_ID, PAYPAL_SECRET);
$client = new \PayPalCheckoutSdk\Core\PayPalHttpClient($environment);
// 读取JSON格式请求体
$requestBody = json_decode(file_get_contents('php://input'), true);
$authorizationId = $requestBody['authorizationId'];

$request = new \PayPalCheckoutSdk\Payments\AuthorizationsGetRequest($authorizationId);
$authorizationResponse = $client->execute($request);
$orderId = $authorizationResponse->result->supplementary_data->related_ids->order_id;

$request = new OrdersGetRequest($orderId);
$orderResponse = $client->execute($request);

// 从purchase_units下的shipping节点读取完整收货信息
$shipping = $orderResponse->result->purchase_units[0]->shipping;
$address = $shipping->address;
$addressData = [
    'recipient_name' => $shipping->name->full_name,
    'address_line1' => $address->address_line_1,
    'address_line2' => $address->address_line_2 ?? '',
    'city' => $address->admin_area_2,
    'state' => $address->admin_area_1,
    'postal_code' => $address->postal_code,
    'country_code' => $address->country_code
];
// 后续将$addressData存入数据库即可
var_dump($addressData);

注意:所有地址字段以服务端调用OrdersGetRequest接口返回的结果为准,不要直接使用前端传回的地址数据,避免数据篡改。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:30:44