@@ -140,21 +140,44 @@ public function doPayment(&$params, $component = 'contribute') {
140
140
$ this ->saveBillingAddressIfRequired ($ params );
141
141
142
142
try {
143
- if (!empty ($ params ['is_recur ' ])) {
144
- $ response = $ this ->gateway ->createCard ($ this ->getCreditCardOptions (array_merge ($ params , array ('action ' => 'Purchase ' )), $ component ))->send ();
145
- }
146
- elseif (!empty ($ params ['token ' ])) {
143
+ if (!empty ($ params ['token ' ])) {
144
+ // If it is not recurring we will have succeeded in an Authorize so we should capture.
145
+ // The only recurring currently working with is_recur + pre-authorize is eWay rapid
146
+ // and, at least in that case, the createCreditCard call ignores any attempt to authorise.
147
+ // that is likely to be a pattern.
148
+ $ action = CRM_Utils_Array::value ('payment_action ' , $ params , empty ($ params ['is_recur ' ]) ? 'capture ' : 'purchase ' );
147
149
$ params ['transactionReference ' ] = ($ params ['token ' ]);
148
- $ response = $ this ->gateway ->capture ($ this ->getCreditCardOptions ($ params, $ component ))
150
+ $ response = $ this ->gateway ->$ action ($ this ->getCreditCardOptions ($ params ))
149
151
->send ();
150
152
}
153
+ elseif (!empty ($ params ['is_recur ' ])) {
154
+ $ response = $ this ->gateway ->createCard ($ this ->getCreditCardOptions (array_merge ($ params , array ('action ' => 'Purchase ' )), $ component ))->send ();
155
+ }
151
156
else {
152
- $ response = $ this ->gateway ->purchase ($ this ->getCreditCardOptions ($ params, $ component ))
157
+ $ response = $ this ->gateway ->purchase ($ this ->getCreditCardOptions ($ params ))
153
158
->send ();
154
159
}
155
160
if ($ response ->isSuccessful ()) {
156
161
// mark order as complete
162
+ if (!empty ($ params ['is_recur ' ])) {
163
+ $ paymentToken = civicrm_api3 ('PaymentToken ' , 'create ' , array (
164
+ 'contact_id ' => $ params ['contactID ' ],
165
+ 'token ' => $ params ['token ' ],
166
+ 'payment_processor_id ' => $ this ->_paymentProcessor ['id ' ],
167
+ 'created_id ' => CRM_Core_Session::getLoggedInContactID (),
168
+ 'email ' => $ params ['email ' ],
169
+ 'billing_first_name ' => $ params ['billing_first_name ' ],
170
+ 'billing_middle_name ' => $ params ['billing_middle_name ' ],
171
+ 'billing_last_name ' => $ params ['billing_last_name ' ],
172
+ 'expiry_date ' => date ("Y-m-t " , strtotime ($ params ['credit_card_exp_date ' ]['Y ' ] . '- ' . $ params ['credit_card_exp_date ' ]['M ' ])),
173
+ 'masked_account_number ' => $ this ->getMaskedCreditCardNumber ($ params ),
174
+ 'ip_address ' => CRM_Utils_System::ipAddress (),
175
+ ));
176
+ civicrm_api3 ('ContributionRecur ' , 'create ' , array ('id ' => $ params ['contributionRecurID ' ], 'payment_token_id ' => $ paymentToken ['id ' ]));
177
+ }
157
178
$ params ['trxn_id ' ] = $ response ->getTransactionReference ();
179
+ $ params ['payment_status_id ' ] = 1 ;
180
+ // @todo fetch masked card, card type, card expiry from params. Eway def provides these.
158
181
//gross_amount ? fee_amount?
159
182
return $ params ;
160
183
}
@@ -343,6 +366,10 @@ private function getCreditCardObjectParams($params) {
343
366
$ cardFields [$ cardField ] = isset ($ params [$ civicrmField ]) ? $ params [$ civicrmField ] : '' ;
344
367
}
345
368
369
+ // Compensate for some unreliability in calling function, especially from pre-Approval.
370
+ if (empty ($ cardFields ['billingCountry ' ]) && isset ($ params ['billing_country_id- ' . $ billingID ])) {
371
+ $ cardFields ['billingCountry ' ] = $ params ['billing_country_id- ' . $ billingID ];
372
+ }
346
373
if (empty ($ cardFields ['email ' ])) {
347
374
if (!empty ($ params ['email- ' . $ billingID ])) {
348
375
$ cardFields ['email ' ] = $ params ['email- ' . $ billingID ];
@@ -394,11 +421,10 @@ private function getSensitiveCreditCardObjectOptions($params) {
394
421
* Get options for credit card.
395
422
*
396
423
* @param array $params
397
- * @param string $component
398
424
*
399
425
* @return array
400
426
*/
401
- private function getCreditCardOptions ($ params, $ component ) {
427
+ private function getCreditCardOptions ($ params ) {
402
428
// Contribution page in 4.4 passes amount - not sure which passes total_amount if any.
403
429
if (isset ($ params ['total_amount ' ])) {
404
430
$ amount = (float ) CRM_Utils_Rule::cleanMoney ($ params ['total_amount ' ]);
@@ -628,6 +654,10 @@ private function getCorePaymentFields() {
628
654
* @return array
629
655
*/
630
656
public function getBillingAddressFields ($ billingLocationID = NULL ) {
657
+ $ fields = $ this ->getProcessorTypeMetadata ('fields ' );
658
+ if (isset ($ fields ['billing_fields ' ])) {
659
+ return $ fields ['billing_fields ' ];
660
+ }
631
661
if (!$ this ->isTransparentRedirect ()) {
632
662
return parent ::getBillingAddressFields ($ billingLocationID );
633
663
}
@@ -896,8 +926,7 @@ protected function supportsFutureRecurStartDate() {
896
926
* @return bool
897
927
*/
898
928
protected function supportsPreApproval () {
899
- $ this ->getProcessorTypeMetadata ('supports_preapproval ' );
900
- return FALSE ;
929
+ return $ this ->getProcessorTypeMetadata ('supports_preapproval ' );
901
930
}
902
931
903
932
/**
@@ -913,7 +942,7 @@ protected function supportsPreApproval() {
913
942
* @return array
914
943
*/
915
944
public function doPreApproval (&$ params ) {
916
- $ this ->_component = ' contribute ' ;
945
+ $ this ->_component = $ params [ ' component ' ] ;
917
946
$ this ->ensurePaymentProcessorTypeIsSet ();
918
947
$ this ->gateway = Omnipay::create (str_replace ('omnipay_ ' , '' , $ this ->_paymentProcessor ['payment_processor_type ' ]));
919
948
$ this ->setProcessorFields ();
@@ -922,11 +951,20 @@ public function doPreApproval(&$params) {
922
951
$ this ->saveBillingAddressIfRequired ($ params );
923
952
924
953
try {
925
- $ response = $ this ->gateway ->authorize ($ this ->getCreditCardOptions ($ params , 'contribute ' ))
926
- ->send ();
954
+ if (!empty ($ params ['is_recur ' ])) {
955
+ $ response = $ this ->gateway ->createCard ($ this ->getCreditCardOptions (array_merge ($ params , array ('action ' => 'Authorize ' ))))->send ();
956
+ }
957
+ else {
958
+ $ response = $ this ->gateway ->authorize ($ this ->getCreditCardOptions ($ params ))
959
+ ->send ();
960
+ }
927
961
if ($ response ->isSuccessful ()) {
928
962
$ params ['trxn_id ' ] = $ params ['token ' ] = $ response ->getTransactionReference ();
929
- $ creditCardPan = '************ ' . substr ($ params ['credit_card_number ' ], -4 );
963
+ if (!empty ($ params ['is_recur ' ])) {
964
+ $ params ['token ' ] = $ response ->getCardReference ();
965
+ }
966
+
967
+ $ creditCardPan = $ this ->getMaskedCreditCardNumber ($ params );
930
968
foreach ($ _SESSION as $ key => $ value ) {
931
969
if (isset ($ value ['values ' ])) {
932
970
foreach ($ value ['values ' ] as $ pageName => $ pageValues ) {
@@ -941,7 +979,7 @@ public function doPreApproval(&$params) {
941
979
unset($ params ['credit_card_number ' ]);
942
980
unset($ params ['cvv2 ' ]);
943
981
return array (
944
- 'pre_approval_parameters ' => array ('token ' => $ response -> getTransactionReference () )
982
+ 'pre_approval_parameters ' => array ('token ' => $ params [ ' token ' ] )
945
983
);
946
984
}
947
985
else {
@@ -1076,5 +1114,30 @@ protected function getProcessorTypeMetadata($parameter) {
1076
1114
return FALSE ;
1077
1115
}
1078
1116
1117
+ /**
1118
+ * @param $params
1119
+ * @return string
1120
+ */
1121
+ protected function getMaskedCreditCardNumber (&$ params ) {
1122
+ $ creditCardPan = '************ ' . substr ($ params ['credit_card_number ' ], -4 );
1123
+ return $ creditCardPan ;
1124
+ }
1125
+
1126
+ /**
1127
+ * Default payment instrument validation.
1128
+ *
1129
+ * Implement the usual Luhn algorithm via a static function in the CRM_Core_Payment_Form if it's a credit card
1130
+ * Not a static function, because I need to check for payment_type.
1131
+ *
1132
+ * @param array $values
1133
+ * @param array $errors
1134
+ */
1135
+ public function validatePaymentInstrument ($ values , &$ errors ) {
1136
+ CRM_Core_Form::validateMandatoryFields ($ this ->getMandatoryFields (), $ values , $ errors );
1137
+ if ($ this ->_paymentProcessor ['payment_type ' ] == 1 ) {
1138
+ CRM_Core_Payment_Form::validateCreditCard ($ values , $ errors , $ this ->_paymentProcessor ['id ' ]);
1139
+ }
1140
+ }
1141
+
1079
1142
}
1080
1143
0 commit comments