Created
March 17, 2016 10:47
-
-
Save bummzack/7fe04392e552ed1473ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Fix an issue with Omnipay 2.0 and the shop system. | |
* The shop assumes that all gateways support the "purchase" method, but that isn't the case. | |
*/ | |
class FixedPurchaseService extends PurchaseService | |
{ | |
/** | |
* Attempt to make a payment. | |
* | |
* @param array $data returnUrl/cancelUrl + customer creditcard and billing/shipping details. | |
* Some keys (e.g. "amount") are overwritten with data from the associated {@link $payment}. | |
* If this array is constructed from user data (e.g. a form submission), please take care | |
* to whitelist accepted fields, in order to ensure sensitive gateway parameters like "freeShipping" can't be set. | |
* If using {@link Form->getData()}, only fields which exist in the form are returned, | |
* effectively whitelisting against arbitrary user input. | |
* @return ResponseInterface omnipay's response class, specific to the chosen gateway. | |
*/ | |
public function purchase($data = array()) | |
{ | |
if ($this->payment->Status !== "Created") { | |
return null; //could be handled better? send payment response? | |
} | |
if (!$this->payment->isInDB()) { | |
$this->payment->write(); | |
} | |
//update success/fail urls | |
$this->update($data); | |
//set the client IP address, if not already set | |
if (!isset($data['clientIp'])) { | |
$data['clientIp'] = Controller::curr()->getRequest()->getIP(); | |
} | |
$gatewaydata = array_merge($data, array( | |
'card' => $this->getCreditCard($data), | |
'amount' => (float)$this->payment->MoneyAmount, | |
'currency' => $this->payment->MoneyCurrency, | |
//set all gateway return/cancel/notify urls to PaymentGatewayController endpoint | |
'returnUrl' => $this->getEndpointURL("complete", $this->payment->Identifier), | |
'cancelUrl' => $this->getEndpointURL("cancel", $this->payment->Identifier), | |
'notifyUrl' => $this->getEndpointURL("notify", $this->payment->Identifier) | |
)); | |
if (!isset($gatewaydata['transactionId'])) { | |
$gatewaydata['transactionId'] = $this->payment->Identifier; | |
} | |
//--- BEGIN FIX | |
$gateway = $this->oGateway(); | |
if($gateway->supportsPurchase()){ | |
$request = $gateway->purchase($gatewaydata); | |
} else { | |
$request = $gateway->authorize($gatewaydata); | |
} | |
//--- END FIX | |
$message = $this->createMessage('PurchaseRequest', $request); | |
$message->SuccessURL = $this->returnurl; | |
$message->FailureURL = $this->cancelurl; | |
$message->write(); | |
$gatewayresponse = $this->createGatewayResponse(); | |
try { | |
$response = $this->response = $request->send(); | |
$gatewayresponse->setOmnipayResponse($response); | |
//update payment model | |
if (GatewayInfo::is_manual($this->payment->Gateway)) { | |
//initiate manual payment | |
$this->createMessage('AuthorizedResponse', $response); | |
$this->payment->Status = 'Authorized'; | |
$this->payment->write(); | |
$gatewayresponse->setMessage("Manual payment authorised"); | |
} elseif ($response->isSuccessful()) { | |
//successful payment | |
$this->createMessage('PurchasedResponse', $response); | |
$this->payment->Status = 'Captured'; | |
$gatewayresponse->setMessage("Payment successful"); | |
$this->payment->write(); | |
$this->payment->extend('onCaptured', $gatewayresponse); | |
} elseif ($response->isRedirect()) { | |
// redirect to off-site payment gateway | |
$this->createMessage('PurchaseRedirectResponse', $response); | |
$this->payment->Status = 'Authorized'; | |
$this->payment->write(); | |
$gatewayresponse->setMessage("Redirecting to gateway"); | |
} else { | |
//handle error | |
$this->createMessage('PurchaseError', $response); | |
$gatewayresponse->setMessage( | |
"Error (" . $response->getCode() . "): " . $response->getMessage() | |
); | |
} | |
} catch (Omnipay\Common\Exception\OmnipayException $e) { | |
$this->createMessage('PurchaseError', $e); | |
$gatewayresponse->setMessage($e->getMessage()); | |
} | |
$gatewayresponse->setRedirectURL($this->getRedirectURL()); | |
return $gatewayresponse; | |
} | |
/** | |
* Finalise this payment, after off-site external processing. | |
* This is ususally only called by PaymentGatewayController. | |
* @return PaymentResponse encapsulated response info | |
*/ | |
public function completePurchase($data = array()) | |
{ | |
$gatewayresponse = $this->createGatewayResponse(); | |
//set the client IP address, if not already set | |
if (!isset($data['clientIp'])) { | |
$data['clientIp'] = Controller::curr()->getRequest()->getIP(); | |
} | |
$gatewaydata = array_merge($data, array( | |
'amount' => (float)$this->payment->MoneyAmount, | |
'currency' => $this->payment->MoneyCurrency | |
)); | |
$this->payment->extend('onBeforeCompletePurchase', $gatewaydata); | |
//--- BEGIN FIX | |
$gateway = $this->oGateway(); | |
if($gateway->supportsPurchase()){ | |
$request = $gateway->completePurchase($gatewaydata); | |
} else { | |
$request = $gateway->completeAuthorize($gatewaydata); | |
} | |
//--- END FIX | |
$this->createMessage('CompletePurchaseRequest', $request); | |
$response = null; | |
try { | |
$response = $this->response = $request->send(); | |
$gatewayresponse->setOmnipayResponse($response); | |
if ($response->isSuccessful()) { | |
$this->createMessage('PurchasedResponse', $response); | |
$this->payment->Status = 'Captured'; | |
$this->payment->write(); | |
$this->payment->extend('onCaptured', $gatewayresponse); | |
} else { | |
$this->createMessage('CompletePurchaseError', $response); | |
} | |
} catch (Omnipay\Common\Exception\OmnipayException $e) { | |
$this->createMessage("CompletePurchaseError", $e); | |
} | |
return $gatewayresponse; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
Name: omnipay-fixes | |
After: shop | |
--- | |
#---- Temporary workaround for https://github.com/burnbright/silverstripe-omnipay/issues/3 | |
Injector: | |
PurchaseService: | |
class: 'FixedPurchaseService' | |
#---- End Temporary workaround |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment