PayPal processing 状态与 Paying Order 支付状态返回 (2026-06-30)

接口变更

user

  • POST /api/orders/payment_status

    • 功能:根据 paypal_order_id 查询 PayPal 支付结果,供 PayPal 返回页轮询使用。
    • 变更:当 PayPal capture 状态为 pending 时,后端会把本地 PayPal checkout session 同步为 processing,响应中的 payment_result 返回 processinglocal_session_status 返回 processing
  • POST /api/work_tasks/paying_order

    • 功能:查询 work task 当前是否存在支付中的订单。
    • 变更:data.paying_order 新增统一支付状态字段 payment_status、操作可用性字段 can_cancel / can_continue_paymentdata.payment.session_status 现在可能返回 processing;PayPal 支付数据新增 paypal_capture_id
  • GET /api/work_tasks/info

    • 功能:获取 work task 详情。
    • 变更:data.paying_orderPOST /api/work_tasks/paying_order 使用同一套支付状态返回结构,包含 payment_statuscan_cancelcan_continue_payment 和嵌套 payment
  • POST /api/worktask_page_event_list/list

    • 功能:获取用户侧 work task 页面事件列表。
    • 变更:当 PayPal capture 进入 pending 并映射为本地 processing 时,会新增一条 type=paypal_processing 的页面事件;当 PayPal 后续变为其他终态时,该事件会自动关闭并从列表消失。
  • POST /api/product_licenses/info

    • 功能:获取 product license 详情。
    • 变更:当 license 存在支付中订单时,响应新增顶层 paying_orderpaymentdata.order 也会带上统一支付状态字段,便于 product 支付详情页展示 PayPal processing 状态。
  • POST /api/product_licenses/continue_payment

    • 功能:继续支付 product license 的支付中订单。
    • 变更:成功响应新增 payment_statuspaying_orderpayment,与 work task 支付订单状态结构保持一致。

artist_center

  • GET /api/artist_center/work_tasks/info

    • 功能:获取 artist 侧 work task 详情。
    • 变更:data.paying_order 与用户侧 GET /api/work_tasks/info 使用同一套支付状态返回结构,包含 payment_statuscan_cancelcan_continue_payment 和嵌套 payment
  • POST /api/artist_center/worktask_page_event_list/list

    • 功能:获取 artist 侧 work task 页面事件列表。
    • 变更:当 PayPal capture 进入 pending 并映射为本地 processing 时,会新增一条 type=paypal_processing 的页面事件;当 PayPal 后续变为其他终态时,该事件会自动关闭并从列表消失。

状态语义

PayPal capture pending 的本地状态

PayPal capture 进入 PENDING 时,表示 PayPal 已开始处理这笔 capture,但商户尚未拿到最终成功或失败结果。后端现在统一映射为本地:

层级字段
PayPal 远端paypal_capture_statuspending
PayPal checkout sessionstatus / local_session_statusprocessing
Paying order 展示状态payment_statusprocessing
PayPal 返回页轮询状态payment_resultprocessing
本地 orderorders.status仍为 paying

processing 期间后端不会结算订单,也不会发放商品或推进 work task 阶段。后续只有在 PayPal capture COMPLETED 后才会完成本地订单;如果 PayPal capture DENIED / DECLINED / FAILED,本地 PayPal checkout session 会转为 failed

Work task 页面事件

PayPal capture 进入 PENDING 时,后端会为对应 work task 创建两条页面事件:

字段
typepaypal_processing
touserartist 各一条
data_idnull
is_closefalse

重复收到 PayPal pending webhook,或 POST /api/orders/payment_status 多次查询到 PayPal capture pending 时,后端不会为同一 work task 重复新增多条 paypal_processing 事件。正常情况下,同一个 work task 只会保持两条未关闭事件:to=user 一条,to=artist 一条。

如果之前的 paypal_processing 事件已经被关闭,后续同一个 work task 再次进入 PayPal processing,后端会重新打开同类型事件,而不是为展示列表追加新的历史消息。

当 PayPal capture 从 pending 变为其他状态时,后端会自动关闭这两条事件,列表接口不再返回。这里的“删除消息”沿用页面事件已有机制,即更新为 is_close=true,不是物理删除。

会关闭 paypal_processing 事件的场景包括:

  • PayPal capture COMPLETED,本地订单支付完成。
  • PayPal capture DENIED / DECLINED / FAILED,本地 PayPal checkout session 转为 failed
  • PayPal 远端 order VOIDED,本地 PayPal checkout session 转为 cancelled
  • 本地 PayPal checkout session 转为 conflicted

payment_status 枚举

payment_status 是订单详情/支付中订单查询场景使用的统一展示状态。

含义前端建议
success本地订单已支付,或支付 session 已完成展示支付成功,刷新业务详情
cancelled本地订单或支付 session 已取消展示已取消
processing支付平台正在处理,当前主要用于 PayPal capture pending展示处理中,禁用继续支付和取消,提示稍后查看或轮询
conflicted本地和支付平台状态冲突,需要人工处理展示异常并提示联系客服
pending订单仍在等待用户完成支付,或暂无明确终态可展示继续支付入口
failed最近一次支付 session 已失败可引导重新发起支付
expired最近一次支付 session 已过期且没有 active session可引导重新发起支付

操作可用性字段

字段类型说明
can_cancelboolean当前 paying order 是否允许取消
can_continue_paymentboolean当前 paying order 是否允许继续支付

当存在 processing / finished / conflicted payment session 时,两个字段都会返回 false

前端应优先使用这两个字段控制按钮,不要只根据 orders.status === "paying" 判断是否可操作。

前端判断字段选择

不建议前端统一使用 session_status 判断支付状态。

推荐规则:

场景前端主判断字段说明
PayPal 返回页轮询payment_result这是 PayPal 返回页专用的最终/处理中判断字段
Work task / product 详情页展示payment_status这是 paying order 的统一展示状态
是否允许取消can_cancel不要用 session_status 自行推导
是否允许继续支付can_continue_payment不要用 session_status 自行推导
展示当前支付渠道的底层状态payment.session_status只作为辅助展示、排查、渠道细节

原因:

  • session_status 只描述当前 active payment session,不一定等于订单的业务支付结果。
  • payment 可能为 null,例如没有 active session,但仍可能有最近一次失败、过期或已完成的支付记录。
  • 支付成功、订单取消等场景可能已经没有需要前端继续操作的 active session,此时应看 payment_statuspayment_result
  • can_cancel / can_continue_payment 已经封装了 processingfinishedconflicted 等阻塞规则,前端不需要重复实现。

接口示例

user

POST /api/orders/payment_status

  • 功能说明:查询 PayPal 支付的当前结果。
  • 变更说明:PayPal capture pending 会同步本地 session 为 processing,并返回 payment_result=processing

请求参数

字段类型必填说明
paypal_order_idstringPayPal order id

请求示例

{
  "paypal_order_id": "2L146185MU803905Y"
}

响应示例:PayPal capture pending

{
  "data": {
    "paypal_order_id": "2L146185MU803905Y",
    "paypal_order_status": "completed",
    "paypal_capture_status": "pending",
    "paypal_capture_id": "3A384378MG7692232",
    "local_order_status": "paying",
    "local_session_status": "processing",
    "payment_result": "processing"
  }
}

前端处理规则

  • payment_result=processing:不要展示支付失败;展示处理中,并继续轮询或提示用户稍后查看。
  • payment_result=pending:表示还没有明确结果,可以继续轮询。
  • payment_result=success:支付最终成功。
  • payment_result=failed / cancelled / conflicted:进入对应终态处理。

错误响应

无新增,沿用原有错误语义。

404:找不到 PayPal checkout session,或当前用户无权查询该 session。

{
  "message": "PayPal checkout session not found"
}

422:参数校验失败。

{
  "message": "The paypal order id field is required."
}

POST /api/work_tasks/paying_order

  • 功能说明:查询 work task 当前是否存在支付中的订单。
  • 变更说明:返回的 paying_order 增加统一状态和操作可用性字段;PayPal capture pending 时会返回 payment_status=processing

请求参数

字段类型必填说明
work_task_idnumberwork task id

请求示例

{
  "work_task_id": 123
}

响应字段变更

data.paying_order 新增字段:

字段类型说明
payment_statusstring统一支付状态,见上方枚举
can_cancelboolean是否允许取消当前 paying order
can_continue_paymentboolean是否允许继续支付当前 paying order

data.payment 字段:

字段类型说明
pay_channelstringpaypal / stripe / alipay
session_statusstring当前支付 session 状态,可能为 pending / processing / conflicted
paypal_order_idstringnullPayPal order id,仅 PayPal 返回
paypal_capture_idstringnullPayPal capture id,仅 PayPal 返回;capture pending 后会有值
pay_urlstringnullPayPal / Alipay 支付跳转地址
checkout_session_idstringnullStripe checkout session id,仅 Stripe 返回
client_secretstringnullStripe client secret,仅 Stripe 返回
out_trade_nostringnullAlipay out_trade_no,仅 Alipay 返回

响应示例:PayPal processing

{
  "data": {
    "has_paying_order": true,
    "paying_order": {
      "id": 456,
      "status": "paying",
      "payment_status": "processing",
      "can_cancel": false,
      "can_continue_payment": false,
      "pay_type": "stage_pay",
      "busable_info": {
        "pay_type": "stage_pay",
        "work_task_id": 123
      },
      "amount": 143,
      "currency_id": 2,
      "init_amount": 1000,
      "init_currency_id": 1,
      "amount_calc_process": {
        "process": []
      },
      "created_at": "2026-06-30T08:00:00.000000Z"
    },
    "payment": {
      "pay_channel": "paypal",
      "session_status": "processing",
      "paypal_order_id": "2L146185MU803905Y",
      "paypal_capture_id": "3A384378MG7692232",
      "pay_url": "https://www.paypal.com/checkoutnow?token=2L146185MU803905Y"
    },
    "pre_calc": {
      "before_amount": {
        "amount": 1000,
        "currency": { "code": "CNY" }
      },
      "after_amount": {
        "amount": 143,
        "currency": { "code": "USD" }
      },
      "process": []
    }
  }
}

前端处理规则

  • payment_status=processing 时,展示“支付处理中”。
  • can_cancel=false 时,不展示或禁用取消按钮。
  • can_continue_payment=false 时,不展示或禁用继续支付按钮。
  • 不要在 processing 时重新创建支付,也不要提示用户退款或重新支付。

错误响应

无新增,沿用原有错误语义。

400:同一 work task 存在多个支付中订单,返回 code=20003

{
  "code": 20003,
  "message": "Work task has multiple paying orders"
}

400:同一支付中订单存在多个 active payment session,返回 code=21003

{
  "code": 21003,
  "message": "Work task paying order has multiple active payment sessions"
}

GET /api/work_tasks/info

  • 功能说明:获取 work task 详情。
  • 变更说明:data.paying_order 现在带有与 POST /api/work_tasks/paying_order 一致的状态字段和嵌套 payment

请求参数

字段类型必填说明
idnumberwork task id

请求示例

GET /api/work_tasks/info?id=123

响应示例:只展示新增字段

{
  "data": {
    "id": 123,
    "paying_order": {
      "id": 456,
      "status": "paying",
      "payment_status": "processing",
      "can_cancel": false,
      "can_continue_payment": false,
      "payment": {
        "pay_channel": "paypal",
        "session_status": "processing",
        "paypal_order_id": "2L146185MU803905Y",
        "paypal_capture_id": "3A384378MG7692232",
        "pay_url": "https://www.paypal.com/checkoutnow?token=2L146185MU803905Y"
      }
    }
  }
}

前端处理规则

  • work_tasks/info 适合页面首次进入时展示当前 paying order 快照。
  • 用户点击继续支付、取消或重新创建支付前,仍建议调用 POST /api/work_tasks/paying_order 获取最新状态。

错误响应

无新增,沿用原有错误语义。

POST /api/worktask_page_event_list/list

  • 功能说明:获取用户侧 work task 页面事件列表。
  • 变更说明:PayPal capture pending 时会返回 type=paypal_processing 事件;PayPal 后续进入其他状态后,该事件会自动关闭并从列表消失。

请求参数

字段类型必填说明
work_task_idnumberwork task id

请求示例

{
  "work_task_id": 123
}

响应示例:PayPal processing 页面事件

{
  "data": [
    {
      "id": 9001,
      "work_task_id": 123,
      "type": "paypal_processing",
      "data_id": null,
      "to": "user",
      "is_close": false,
      "data": null,
      "created_at": "2026-06-30T08:00:00.000000Z",
      "updated_at": "2026-06-30T08:00:00.000000Z"
    }
  ]
}

前端处理规则

  • 用户侧只会看到 to=userpaypal_processing 事件。
  • 该事件表示 PayPal 已进入处理中状态,不代表支付成功或失败。
  • 当 PayPal capture 后续完成、失败、取消或冲突后,后端会自动关闭该事件;前端重新拉取列表时不应再展示。
  • 事件详情没有额外关联数据,data_id=nulldata=null

错误响应

无新增,沿用原有错误语义。

POST /api/product_licenses/info

  • 功能说明:获取 product license 详情。
  • 变更说明:product license 详情现在也能通过 paying_order / payment 查询支付中订单状态,和 work task 使用同一套字段语义。

请求参数

字段类型必填说明
license_idnumberproduct license id

请求示例

{
  "license_id": 789
}

响应字段变更

字段类型说明
data.order.payment_statusstringnulllicense 关联订单的统一支付状态
data.order.can_cancelbooleannull关联订单是否可取消
data.order.can_continue_paymentbooleannull关联订单是否可继续支付
data.order.paymentobjectnull关联订单当前 active payment session
data.paying_orderobjectnull当关联订单为 paying 时返回,否则为 null
data.paymentobjectnull当存在 active payment session 时返回,否则为 null

响应示例:PayPal processing

{
  "data": {
    "id": 789,
    "status": "paying",
    "order": {
      "id": 456,
      "status": "paying",
      "payment_status": "processing",
      "can_cancel": false,
      "can_continue_payment": false,
      "payment": {
        "pay_channel": "paypal",
        "session_status": "processing",
        "paypal_order_id": "2L146185MU803905Y",
        "paypal_capture_id": "3A384378MG7692232",
        "pay_url": "https://www.paypal.com/checkoutnow?token=2L146185MU803905Y"
      }
    },
    "paying_order": {
      "id": 456,
      "status": "paying",
      "payment_status": "processing",
      "can_cancel": false,
      "can_continue_payment": false
    },
    "payment": {
      "pay_channel": "paypal",
      "session_status": "processing",
      "paypal_order_id": "2L146185MU803905Y",
      "paypal_capture_id": "3A384378MG7692232",
      "pay_url": "https://www.paypal.com/checkoutnow?token=2L146185MU803905Y"
    }
  }
}

错误响应

无新增,沿用原有错误语义。

403:当前用户无权查看该 license。

{
  "message": "Unauthorized"
}

422:参数校验失败。

{
  "message": "The license id field is required."
}

POST /api/product_licenses/continue_payment

  • 功能说明:继续支付 product license 的支付中订单。
  • 变更说明:成功响应新增 payment_statuspaying_orderpayment,便于前端在继续支付后同步刷新本地支付状态。

请求参数

字段类型必填说明
license_idnumberproduct license id

请求示例

{
  "license_id": 789
}

响应示例:继续 PayPal pending 支付

{
  "data": {
    "pay_channel": "paypal",
    "pay_data": {
      "pay_url": "https://www.paypal.com/checkoutnow?token=2L146185MU803905Y",
      "paypal_order_id": "2L146185MU803905Y"
    },
    "status": "paying",
    "payment_status": "pending",
    "paying_order": {
      "id": 456,
      "status": "paying",
      "payment_status": "pending",
      "can_cancel": true,
      "can_continue_payment": true
    },
    "payment": {
      "pay_channel": "paypal",
      "session_status": "pending",
      "paypal_order_id": "2L146185MU803905Y",
      "paypal_capture_id": null,
      "pay_url": "https://www.paypal.com/checkoutnow?token=2L146185MU803905Y"
    },
    "amount": 143,
    "currency": {
      "code": "USD"
    },
    "pay_url": "https://www.paypal.com/checkoutnow?token=2L146185MU803905Y",
    "paypal_order_id": "2L146185MU803905Y"
  }
}

错误响应

400:支付正在处理中,返回 code=21002。当 PayPal session 已经是 processing 时,后端不会返回继续支付链接。

{
  "code": 21002,
  "message": "Payment is being processed"
}

400:支付状态冲突,需要人工处理。

{
  "code": 21001,
  "message": "PayPal payment conflict"
}

403:当前用户无权操作该 license。

{
  "message": "Unauthorized"
}

artist_center

GET /api/artist_center/work_tasks/info

  • 功能说明:获取 artist 侧 work task 详情。
  • 变更说明:返回的 data.paying_order 现在与用户侧 GET /api/work_tasks/info 保持一致,可以直接读取 payment_statuscan_cancelcan_continue_payment 和嵌套 payment

请求参数

字段类型必填说明
idnumberwork task id

请求示例

GET /api/artist_center/work_tasks/info?id=123

响应示例:只展示新增字段

{
  "data": {
    "id": 123,
    "paying_order": {
      "id": 456,
      "status": "paying",
      "payment_status": "processing",
      "can_cancel": false,
      "can_continue_payment": false,
      "payment": {
        "pay_channel": "paypal",
        "session_status": "processing",
        "paypal_order_id": "2L146185MU803905Y",
        "paypal_capture_id": "3A384378MG7692232",
        "pay_url": "https://www.paypal.com/checkoutnow?token=2L146185MU803905Y"
      }
    }
  }
}

前端处理规则

  • Artist 侧 work task 详情页可以直接使用 data.paying_order.payment_status 展示支付状态。
  • Artist 侧不应自行用 payment.session_status 推导业务状态;按钮和提示优先使用 payment_statuscan_cancelcan_continue_payment
  • 当没有支付中订单时,data.paying_ordernull

错误响应

无新增,沿用原有错误语义。

POST /api/artist_center/worktask_page_event_list/list

  • 功能说明:获取 artist 侧 work task 页面事件列表。
  • 变更说明:PayPal capture pending 时会返回 type=paypal_processing 事件;PayPal 后续进入其他状态后,该事件会自动关闭并从列表消失。

请求参数

字段类型必填说明
work_task_idnumberwork task id

请求示例

{
  "work_task_id": 123
}

响应示例:PayPal processing 页面事件

{
  "data": [
    {
      "id": 9002,
      "work_task_id": 123,
      "type": "paypal_processing",
      "data_id": null,
      "to": "artist",
      "is_close": false,
      "data": null,
      "created_at": "2026-06-30T08:00:00.000000Z",
      "updated_at": "2026-06-30T08:00:00.000000Z"
    }
  ]
}

前端处理规则

  • Artist 侧只会看到 to=artistpaypal_processing 事件。
  • 该事件表示买家的 PayPal 支付正在由 PayPal 处理,不代表支付成功或失败。
  • 当 PayPal capture 后续完成、失败、取消或冲突后,后端会自动关闭该事件;前端重新拉取列表时不应再展示。
  • 事件详情没有额外关联数据,data_id=nulldata=null

错误响应

无新增,沿用原有错误语义。

兼容性说明

  • 本次是响应字段新增和状态语义调整;旧字段未移除。
  • Work task 支付页和 product 支付页都应优先读取 payment_statuscan_cancel / can_continue_payment 控制 UI。
  • session_status 只用于展示当前支付 session 的底层状态,不作为前端统一业务判断字段。
  • PayPal processing 不等于失败,也不等于已支付成功;不要触发退款、发货、发放 product license 文件或推进 work task 阶段。
  • PayPal processing 期间如果用户刷新页面,前端应通过 work_tasks/infowork_tasks/paying_orderproduct_licenses/info 继续展示处理中状态。
  • PayPal 返回页仍应以 POST /api/orders/payment_statuspayment_result 为准;订单详情页使用 payment_status
  • 如果看到 payment_status=processingcan_cancel=falsecan_continue_payment=false,前端应禁用取消和继续支付入口,提示等待 PayPal 最终处理结果。