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

如何整合代码实现Drupal中uc_paypal.module的PayPal订单退款按钮?

Drupal Ubercart PayPal 订单退款按钮实现方案

1. 在订单详情页添加退款按钮

在Ubercart订单详情模板(如uc-order.tpl.php)或自定义模块中,针对已完成且存在有效PayPal交易的订单显示退款按钮:

<?php
// 校验订单状态与用户退款权限
if ($order->order_status == 'completed' && user_access('refund paypal orders')) {
  // 生成带CSRF校验的退款链接
  $refund_link = url('uc_paypal/refund/' . $order->order_id, ['query' => ['token' => drupal_get_token($order->order_id)]]);
  print '<a href="' . $refund_link . '" class="button confirm">PayPal 退款</a>';
}
?>

2. 注册退款路由与回调

在自定义模块(如uc_paypal_refund.module)中通过hook_menu注册退款处理路由:

/**
 * Implements hook_menu().
 */
function uc_paypal_refund_menu() {
  $items = [];
  $items['uc_paypal/refund/%'] = [
    'title' => 'PayPal 退款处理',
    'page callback' => 'uc_paypal_refund_process',
    'page arguments' => [2],
    'access arguments' => ['refund paypal orders'],
    'type' => MENU_CALLBACK,
  ];
  return $items;
}

3. 核心退款逻辑实现

整合交易ID查询、PayPal API请求与结果处理:

/**
 * 处理PayPal退款请求
 */
function uc_paypal_refund_process($order_id) {
  // CSRF校验
  if (!drupal_valid_token($_GET['token'], $order_id)) {
    drupal_set_message('无效请求', 'error');
    drupal_goto('admin/store/orders/' . $order_id);
  }

  $order = uc_order_load($order_id);
  if (!$order || $order->order_status != 'completed') {
    drupal_set_message('订单状态不支持退款', 'error');
    drupal_goto('admin/store/orders/' . $order_id);
  }

  // 1. 查询订单对应的PayPal交易ID(TxnId)
  $txn_id = db_select('uc_paypal_ipn', 'ipn')
    ->fields('ipn', ['txn_id'])
    ->condition('order_id', $order_id)
    ->condition('payment_status', 'Completed')
    ->execute()
    ->fetchField();

  if (!$txn_id) {
    drupal_set_message('未找到有效PayPal交易记录', 'error');
    drupal_goto('admin/store/orders/' . $order_id);
  }

  // 2. 构造PayPal v2退款API参数
  $refund_amount = [
    'value' => uc_currency_format($order->order_total, FALSE, FALSE, FALSE),
    'currency_code' => uc_store_currency(),
  ];
  $request_data = [
    'amount' => $refund_amount,
    'note_to_payer' => '订单#' . $order_id . ' 退款',
  ];

  // 3. 调用uc_paypal模块内置API请求函数
  // PayPal v2退款端点:/v2/payments/captures/{capture_id}/refund
  $endpoint = '/v2/payments/captures/' . $txn_id . '/refund';
  $response = uc_paypal_api_request($endpoint, $request_data, 'POST');

  // 4. 处理API响应
  if (isset($response['status']) && $response['status'] == 'COMPLETED') {
    uc_order_update_status($order_id, 'refunded', 'PayPal退款完成,退款ID:' . $response['id']);
    drupal_set_message('退款已成功提交至PayPal', 'status');
  } else {
    $error_msg = isset($response['message']) ? $response['message'] : '退款请求失败';
    drupal_set_message('退款失败:' . $error_msg, 'error');
  }

  drupal_goto('admin/store/orders/' . $order_id);
}

4. 添加退款权限配置

通过hook_permission添加权限控制,确保仅授权用户可执行退款:

/**
 * Implements hook_permission().
 */
function uc_paypal_refund_permission() {
  return [
    'refund paypal orders' => [
      'title' => t('Refund PayPal orders'),
      'description' => t('Allow users to refund completed PayPal orders.'),
    ],
  ];
}

关键注意事项

  • 确认uc_paypal_api_request函数支持PayPal v2 API格式,若原模块仅兼容v1,需调整函数请求头(添加Content-Type: application/json)
  • 测试阶段请使用PayPal沙箱环境,避免真实资金损失
  • 如需支持部分退款,修改$refund_amount['value']为指定金额即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 17:45:33