@@ -140,21 +140,44 @@ public function doPayment(&$params, $component = 'contribute') {
140140 $ this ->saveBillingAddressIfRequired ($ params );
141141
142142 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 ' );
147149 $ params ['transactionReference ' ] = ($ params ['token ' ]);
148- $ response = $ this ->gateway ->capture ($ this ->getCreditCardOptions ($ params, $ component ))
150+ $ response = $ this ->gateway ->$ action ($ this ->getCreditCardOptions ($ params ))
149151 ->send ();
150152 }
153+ elseif (!empty ($ params ['is_recur ' ])) {
154+ $ response = $ this ->gateway ->createCard ($ this ->getCreditCardOptions (array_merge ($ params , array ('action ' => 'Purchase ' )), $ component ))->send ();
155+ }
151156 else {
152- $ response = $ this ->gateway ->purchase ($ this ->getCreditCardOptions ($ params, $ component ))
157+ $ response = $ this ->gateway ->purchase ($ this ->getCreditCardOptions ($ params ))
153158 ->send ();
154159 }
155160 if ($ response ->isSuccessful ()) {
156161 // 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+ }
157178 $ 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.
158181 //gross_amount ? fee_amount?
159182 return $ params ;
160183 }
@@ -343,6 +366,10 @@ private function getCreditCardObjectParams($params) {
343366 $ cardFields [$ cardField ] = isset ($ params [$ civicrmField ]) ? $ params [$ civicrmField ] : '' ;
344367 }
345368
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+ }
346373 if (empty ($ cardFields ['email ' ])) {
347374 if (!empty ($ params ['email- ' . $ billingID ])) {
348375 $ cardFields ['email ' ] = $ params ['email- ' . $ billingID ];
@@ -394,11 +421,10 @@ private function getSensitiveCreditCardObjectOptions($params) {
394421 * Get options for credit card.
395422 *
396423 * @param array $params
397- * @param string $component
398424 *
399425 * @return array
400426 */
401- private function getCreditCardOptions ($ params, $ component ) {
427+ private function getCreditCardOptions ($ params ) {
402428 // Contribution page in 4.4 passes amount - not sure which passes total_amount if any.
403429 if (isset ($ params ['total_amount ' ])) {
404430 $ amount = (float ) CRM_Utils_Rule::cleanMoney ($ params ['total_amount ' ]);
@@ -628,6 +654,10 @@ private function getCorePaymentFields() {
628654 * @return array
629655 */
630656 public function getBillingAddressFields ($ billingLocationID = NULL ) {
657+ $ fields = $ this ->getProcessorTypeMetadata ('fields ' );
658+ if (isset ($ fields ['billing_fields ' ])) {
659+ return $ fields ['billing_fields ' ];
660+ }
631661 if (!$ this ->isTransparentRedirect ()) {
632662 return parent ::getBillingAddressFields ($ billingLocationID );
633663 }
@@ -896,8 +926,7 @@ protected function supportsFutureRecurStartDate() {
896926 * @return bool
897927 */
898928 protected function supportsPreApproval () {
899- $ this ->getProcessorTypeMetadata ('supports_preapproval ' );
900- return FALSE ;
929+ return $ this ->getProcessorTypeMetadata ('supports_preapproval ' );
901930 }
902931
903932 /**
@@ -913,7 +942,7 @@ protected function supportsPreApproval() {
913942 * @return array
914943 */
915944 public function doPreApproval (&$ params ) {
916- $ this ->_component = ' contribute ' ;
945+ $ this ->_component = $ params [ ' component ' ] ;
917946 $ this ->ensurePaymentProcessorTypeIsSet ();
918947 $ this ->gateway = Omnipay::create (str_replace ('omnipay_ ' , '' , $ this ->_paymentProcessor ['payment_processor_type ' ]));
919948 $ this ->setProcessorFields ();
@@ -922,11 +951,20 @@ public function doPreApproval(&$params) {
922951 $ this ->saveBillingAddressIfRequired ($ params );
923952
924953 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+ }
927961 if ($ response ->isSuccessful ()) {
928962 $ 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 );
930968 foreach ($ _SESSION as $ key => $ value ) {
931969 if (isset ($ value ['values ' ])) {
932970 foreach ($ value ['values ' ] as $ pageName => $ pageValues ) {
@@ -941,7 +979,7 @@ public function doPreApproval(&$params) {
941979 unset($ params ['credit_card_number ' ]);
942980 unset($ params ['cvv2 ' ]);
943981 return array (
944- 'pre_approval_parameters ' => array ('token ' => $ response -> getTransactionReference () )
982+ 'pre_approval_parameters ' => array ('token ' => $ params [ ' token ' ] )
945983 );
946984 }
947985 else {
@@ -1076,5 +1114,30 @@ protected function getProcessorTypeMetadata($parameter) {
10761114 return FALSE ;
10771115 }
10781116
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+
10791142}
10801143
0 commit comments