fix(payment): unify and harden payment attempts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -546,8 +546,15 @@ trait OrderRepositoryCore {
|
||||
|
||||
/**
|
||||
* Resolve a local order from a provider out_trade_no (base or attempt-suffixed).
|
||||
*
|
||||
* The authoritative mapping is the order's own meta (provider_out_trade_no /
|
||||
* provider_out_trade_nos); the prefix heuristic is only a fallback and must
|
||||
* never be the sole resolver, otherwise a truncated attempt number would
|
||||
* strand a real payment.
|
||||
*/
|
||||
public function resolve_by_out_trade_no(string $out_trade_no): ?array {
|
||||
global $wpdb;
|
||||
|
||||
$out_trade_no = sanitize_text_field($out_trade_no);
|
||||
if ($out_trade_no === '') {
|
||||
return null;
|
||||
@@ -558,8 +565,37 @@ trait OrderRepositoryCore {
|
||||
return $direct;
|
||||
}
|
||||
|
||||
// Resume attempts: {order_number}P{n}
|
||||
if (preg_match('/^(AKS[0-9]{10,})P([0-9]{1,3})$/', $out_trade_no, $m)) {
|
||||
// Authoritative: the attempt number was recorded in the order note JSON.
|
||||
$needle = '"provider_out_trade_no":"' . $out_trade_no . '"';
|
||||
$row = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM {$this->table()} WHERE note LIKE %s ORDER BY id DESC LIMIT 1",
|
||||
'%' . $wpdb->esc_like($needle) . '%'
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
if (is_array($row)) {
|
||||
return $this->normalize_row($row);
|
||||
}
|
||||
|
||||
// Superseded attempts stay in the history array.
|
||||
$history_needle = '"' . $out_trade_no . '"';
|
||||
$row = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM {$this->table()}
|
||||
WHERE note LIKE %s AND note LIKE %s
|
||||
ORDER BY id DESC LIMIT 1",
|
||||
'%' . $wpdb->esc_like('"provider_out_trade_nos"') . '%',
|
||||
'%' . $wpdb->esc_like($history_needle) . '%'
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
if (is_array($row)) {
|
||||
return $this->normalize_row($row);
|
||||
}
|
||||
|
||||
// Last resort: {order_number}P{n} prefix heuristic.
|
||||
if (preg_match('/^(.+)P([0-9]{1,3})$/', $out_trade_no, $m)) {
|
||||
$base = $this->get($m[1]);
|
||||
if ($base) {
|
||||
return $base;
|
||||
|
||||
Reference in New Issue
Block a user