Merge branch 'feature/candidate_payments' into homo_experimental
This commit is contained in:
@@ -341,8 +341,9 @@ class TelepagosWebhookTest extends TestCase
|
||||
->firstOrFail();
|
||||
$this->assertEqualsCanonicalizing(
|
||||
[$firstPurchase->id, $secondPurchase->id, $thirdPurchase->id],
|
||||
$payment->matched_purchase_ids,
|
||||
$payment->candidates()->pluck('compra_id')->all(),
|
||||
);
|
||||
$this->assertSame(3, $payment->candidates()->where('match_reason', 'ambiguous_exact_match')->count());
|
||||
$this->assertDatabaseHas('compras', [
|
||||
'id' => $firstPurchase->id,
|
||||
'status' => Purchase::STATUS_PENDING_PAYMENT,
|
||||
@@ -357,6 +358,183 @@ class TelepagosWebhookTest extends TestCase
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_transfer_webhook_records_near_amount_only_with_exact_dni_or_exact_amount_with_different_dni(): void
|
||||
{
|
||||
config(['purchase.transfer_candidate_amount_tolerance_percentage' => 5]);
|
||||
|
||||
$tenant = $this->createTenant('candidates', 'Candidates', 'candidates.com.ar');
|
||||
$this->configureTelepagosIntegration($tenant);
|
||||
|
||||
$nearAmountVariant = $this->createVariantForTenant('candidates', 10, '52.00', 'near');
|
||||
$exactAmountVariant = $this->createVariantForTenant('candidates', 10, '50.00', 'exact');
|
||||
$distanceTwoExactAmountVariant = $this->createVariantForTenant('candidates', 10, '50.00', 'distance-two');
|
||||
$farExactAmountVariant = $this->createVariantForTenant('candidates', 10, '50.00', 'far-exact');
|
||||
$nearAmountDifferentDniVariant = $this->createVariantForTenant('candidates', 10, '51.00', 'near-other-dni');
|
||||
$outsideRangeVariant = $this->createVariantForTenant('candidates', 10, '100.00', 'outside');
|
||||
|
||||
$nearAmountPurchase = $this->createPendingTransferPurchase(
|
||||
$tenant,
|
||||
User::factory()->create()->id,
|
||||
$nearAmountVariant->id,
|
||||
1,
|
||||
'12345678',
|
||||
);
|
||||
$exactAmountDifferentDniPurchase = $this->createPendingTransferPurchase(
|
||||
$tenant,
|
||||
User::factory()->create()->id,
|
||||
$exactAmountVariant->id,
|
||||
1,
|
||||
'12345687',
|
||||
);
|
||||
$farExactAmountDifferentDniPurchase = $this->createPendingTransferPurchase(
|
||||
$tenant,
|
||||
User::factory()->create()->id,
|
||||
$farExactAmountVariant->id,
|
||||
1,
|
||||
'87654321',
|
||||
);
|
||||
$distanceTwoExactAmountPurchase = $this->createPendingTransferPurchase(
|
||||
$tenant,
|
||||
User::factory()->create()->id,
|
||||
$distanceTwoExactAmountVariant->id,
|
||||
1,
|
||||
'12345087',
|
||||
);
|
||||
$nearAmountDifferentDniPurchase = $this->createPendingTransferPurchase(
|
||||
$tenant,
|
||||
User::factory()->create()->id,
|
||||
$nearAmountDifferentDniVariant->id,
|
||||
1,
|
||||
'87654321',
|
||||
);
|
||||
$outsideRangePurchase = $this->createPendingTransferPurchase(
|
||||
$tenant,
|
||||
User::factory()->create()->id,
|
||||
$outsideRangeVariant->id,
|
||||
1,
|
||||
'12345678',
|
||||
);
|
||||
|
||||
Http::fake([
|
||||
'https://api.telepagos.com.ar/v2/auth/token' => Http::response([
|
||||
'status' => 'ok',
|
||||
'token' => 'test-token',
|
||||
'expires_at' => now()->addHour()->toIso8601String(),
|
||||
]),
|
||||
'https://api.telepagos.com.ar/v2/payment/cashin/candidates' => Http::response([
|
||||
'status' => 'ok',
|
||||
'data' => [
|
||||
'amount' => 50,
|
||||
'operation_id' => 1,
|
||||
'transaction_id' => 'tx-candidates',
|
||||
'buyer' => ['cuit' => '20123456789'],
|
||||
],
|
||||
]),
|
||||
]);
|
||||
|
||||
$this->postJson('/api/webhooks/telepagos/candidates', ['id' => 'candidates'])
|
||||
->assertOk()
|
||||
->assertJsonPath('status', 'success');
|
||||
|
||||
$payment = TelepagosPayment::query()
|
||||
->where('transaction_id', 'tx-candidates')
|
||||
->firstOrFail();
|
||||
|
||||
$this->assertNull($payment->compra_id);
|
||||
$this->assertEqualsCanonicalizing([
|
||||
$nearAmountPurchase->id,
|
||||
$exactAmountDifferentDniPurchase->id,
|
||||
$distanceTwoExactAmountPurchase->id,
|
||||
], $payment->candidates()->pluck('compra_id')->all());
|
||||
$this->assertDatabaseHas('telepagos_payment_candidates', [
|
||||
'telepagos_payment_id' => $payment->id,
|
||||
'compra_id' => $nearAmountPurchase->id,
|
||||
'dni_matches' => true,
|
||||
'dni_distance' => 0,
|
||||
'payment_dni' => '12345678',
|
||||
'purchase_dni' => '12345678',
|
||||
'amount_matches' => false,
|
||||
'payment_amount' => 50,
|
||||
'purchase_amount' => 52,
|
||||
'amount_difference' => 2,
|
||||
'match_reason' => 'exact_dni_near_amount',
|
||||
'confidence' => 'high',
|
||||
]);
|
||||
$this->assertDatabaseHas('telepagos_payment_candidates', [
|
||||
'telepagos_payment_id' => $payment->id,
|
||||
'compra_id' => $exactAmountDifferentDniPurchase->id,
|
||||
'dni_matches' => false,
|
||||
'dni_distance' => 1,
|
||||
'payment_dni' => '12345678',
|
||||
'purchase_dni' => '12345687',
|
||||
'amount_matches' => true,
|
||||
'payment_amount' => 50,
|
||||
'purchase_amount' => 50,
|
||||
'amount_difference' => 0,
|
||||
'match_reason' => 'exact_amount_near_dni',
|
||||
'confidence' => 'medium',
|
||||
]);
|
||||
$this->assertDatabaseHas('telepagos_payment_candidates', [
|
||||
'telepagos_payment_id' => $payment->id,
|
||||
'compra_id' => $distanceTwoExactAmountPurchase->id,
|
||||
'dni_matches' => false,
|
||||
'dni_distance' => 2,
|
||||
'payment_dni' => '12345678',
|
||||
'purchase_dni' => '12345087',
|
||||
'amount_matches' => true,
|
||||
'match_reason' => 'exact_amount_near_dni',
|
||||
]);
|
||||
$this->assertDatabaseMissing('telepagos_payment_candidates', [
|
||||
'telepagos_payment_id' => $payment->id,
|
||||
'compra_id' => $farExactAmountDifferentDniPurchase->id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('telepagos_payment_candidates', [
|
||||
'telepagos_payment_id' => $payment->id,
|
||||
'compra_id' => $nearAmountDifferentDniPurchase->id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('telepagos_payment_candidates', [
|
||||
'telepagos_payment_id' => $payment->id,
|
||||
'compra_id' => $outsideRangePurchase->id,
|
||||
]);
|
||||
$this->assertSame(Purchase::STATUS_PENDING_PAYMENT, $nearAmountPurchase->fresh()->status);
|
||||
$this->assertSame(Purchase::STATUS_PENDING_PAYMENT, $exactAmountDifferentDniPurchase->fresh()->status);
|
||||
|
||||
$higherPriorityPayment = TelepagosPayment::query()->create([
|
||||
'cuit_buyer' => '20123456789',
|
||||
'amount' => 52,
|
||||
'operation_id' => 1,
|
||||
'transaction_id' => 'tx-primary-candidate',
|
||||
]);
|
||||
$higherPriorityPayment->candidates()->create([
|
||||
'compra_id' => $nearAmountPurchase->id,
|
||||
'dni_matches' => true,
|
||||
'dni_distance' => 0,
|
||||
'payment_dni' => '12345678',
|
||||
'purchase_dni' => '12345678',
|
||||
'amount_matches' => true,
|
||||
'payment_amount' => 52,
|
||||
'purchase_amount' => 52,
|
||||
'amount_difference' => 0,
|
||||
'match_reason' => 'ambiguous_exact_match',
|
||||
'confidence' => 'exact',
|
||||
]);
|
||||
|
||||
app(CheckoutService::class)->submitForReview($nearAmountPurchase->fresh());
|
||||
$buyer = User::query()->findOrFail($nearAmountPurchase->user_id);
|
||||
|
||||
$this->actingAs($buyer, 'sanctum')
|
||||
->getJson("/api/tenants/candidates/compras/{$nearAmountPurchase->id}")
|
||||
->assertOk()
|
||||
->assertJsonPath('data.status', Purchase::STATUS_IN_REVIEW)
|
||||
->assertJsonPath('data.payment_verification.status', 'candidate')
|
||||
->assertJsonPath('data.payment_verification.candidate_count', 2)
|
||||
->assertJsonPath('data.payment_verification.primary.reason', 'ambiguous_exact_match')
|
||||
->assertJsonPath('data.payment_verification.primary.amount_difference', '0.00')
|
||||
->assertJsonPath('data.payment_verification.primary.confidence', 'exact')
|
||||
->assertJsonPath('data.payment_verification.reasons.0', 'ambiguous_exact_match')
|
||||
->assertJsonPath('data.payment_verification.reasons.1', 'exact_dni_near_amount');
|
||||
}
|
||||
|
||||
public function test_webhook_confirms_a_purchase_with_tickets_enabled(): void
|
||||
{
|
||||
$tenant = $this->createTenant('expired-ticket', 'Expired Ticket', 'expired-ticket.com.ar');
|
||||
|
||||
Reference in New Issue
Block a user