-
Notifications
You must be signed in to change notification settings - Fork 3
/
PaymentCaptureAction.php
80 lines (74 loc) · 2.9 KB
/
PaymentCaptureAction.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php namespace SmashPig\PaymentProviders\Adyen\Actions;
use SmashPig\Core\Actions\IListenerMessageAction;
use SmashPig\Core\Context;
use SmashPig\Core\DataStores\QueueWrapper;
use SmashPig\Core\Logging\TaggedLogger;
use SmashPig\Core\Messages\ListenerMessage;
use SmashPig\PaymentProviders\Adyen\ExpatriatedMessages\Authorisation;
use SmashPig\PaymentProviders\Adyen\Jobs\ProcessCaptureRequestJob;
use SmashPig\PaymentProviders\Adyen\Jobs\RecordCaptureJob;
/**
* When an authorization message from Adyen comes in, we need to either place
* a capture request into the job queue, or we need to slay its orphan because
* the transaction failed.
*/
class PaymentCaptureAction implements IListenerMessageAction {
public const METHODS_RECORDED_ON_AUTHORISATION = [
'ideal', 'onlineBanking_CZ'
];
public function execute( ListenerMessage $msg ): bool {
$tl = new TaggedLogger( 'PaymentCaptureAction' );
if ( $msg instanceof Authorisation ) {
if ( $msg->success || $msg->isEndedAutoRescue() ) {
$isAutoRescue = $msg->isSuccessfulAutoRescue() || $msg->isEndedAutoRescue();
// Ignore subsequent recurring IPNs when it's not an ongoing auto rescue (means it's a success or cancel auto rescue)
if ( !$isAutoRescue && $msg->isRecurringInstallment() ) {
return true;
}
// For iDEAL, treat this as the final notification of success. We don't
// need to make any more API calls, just record it in Civi.
if (
isset( $msg->paymentMethod ) &&
in_array( $msg->paymentMethod, self::METHODS_RECORDED_ON_AUTHORISATION, true )
) {
$tl->info(
"Adding Adyen record capture job for {$msg->currency} {$msg->amount} " .
"with psp reference {$msg->pspReference}."
);
$job = RecordCaptureJob::factory( $msg );
QueueWrapper::push( 'jobs-adyen', $job );
} else {
$providerConfig = Context::get()->getProviderConfiguration();
if ( !$providerConfig->val( 'capture-from-ipn-listener' ) && !$isAutoRescue ) {
return true;
}
// Here we need to capture the payment, the job runner will collect the
// orphan message
$tl->info(
"Adding Adyen capture job for {$msg->currency} {$msg->amount} " .
"with psp reference {$msg->pspReference}."
);
$job = ProcessCaptureRequestJob::factory( $msg );
$queueName = 'jobs-adyen';
$jobQueueCount = $providerConfig->val(
'capture-job-queue-count'
);
if ( $jobQueueCount > 1 ) {
$queueNum = rand( 1, $jobQueueCount );
$queueName .= "-$queueNum";
}
QueueWrapper::push( $queueName, $job );
}
} else {
// Here we could decide to delete the data from the pending
// table, but we don't because donors can potentially re-use
// a merchant reference by reloading an Adyen hosted page.
$tl->info(
"Adyen payment with psp reference {$msg->pspReference} " .
"reported status failed: '{$msg->reason}'."
);
}
}
return true;
}
}