fix(security): unique payment reference_id, reject replayed callbacks (H3)
reference_id (the gateway's settled-transaction ref) was not unique, so the same successful callback — or a RefNum replayed onto another order — could credit twice. Add a unique index (NULL until success, so pending/failed rows don't collide) and an application-level pre-check in the callback that fails the payment if the reference already belongs to another order. The unique index is the hard backstop behind the check. Regression: PaymentCallbackAmountTest::testReplayedGatewayReferenceIsRejected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -54,6 +54,11 @@ class PaymentRepository extends ServiceEntityRepository
|
||||
return $this->findOneBy(['orderId' => $orderId]);
|
||||
}
|
||||
|
||||
public function findByReferenceId(string $referenceId): ?Payment
|
||||
{
|
||||
return $this->findOneBy(['referenceId' => $referenceId]);
|
||||
}
|
||||
|
||||
public function findPendingByAppointment(Appointment $appointment): ?Payment
|
||||
{
|
||||
return $this->findOneBy([
|
||||
|
||||
Reference in New Issue
Block a user