为了给你一些背景知识,我写了一个使用Omnipay包装PaypalExpress和SagePayDirect的支付类。它工作正常,但是,我还需要添加SagePayServer。不幸的是,经过三天的工作,我无法让SagePayServer正常工作。我一直得到" RedirectionURL 5006"错误,这只是一个包罗万象的错误。 SagePay绝对是我的网址,但由于某种原因,付款失败,它给出了这个错误。
SagePay和OmniPay都有糟糕的文档和缺乏良好的工作示例,所以感谢任何帮助。
这是我的代码的核心(需要进行大量调整才能使Stack Overflow更简单):
<?php
use Omnipay\Omnipay;
class PaymentHandler {
public
$transactionID;
private
$gateway,
$config,
$card,
$order,
$options;
public function __construct() {
$this->order = new Order();
$this->createTransactionID();
$this->setOptions();
$this->gateway = Omnipay::create("SagePay_Server");
$this->gateway->setTestMode($this->options["testMode"]);
$this->gateway->setVendor($this->options["vendorName"]);
}
private function prepareSagePayServer() {
$billingAddress = $this->order->getAddresses("billing");
$shippingAddress = $this->order->getAddresses("delivery");
$billingCountry = $this->getCountryISO($billingAddress["country"]);
$shippingCountry = $this->getCountryISO($shippingAddress["country"]);
$this->card = array(
'firstName' => $billingAddress["firstname"],
'lastName' => $billingAddress["surname"],
'billingFirstName' => $billingAddress["firstname"],
'billingLastName' => $billingAddress["surname"],
'billingAddress1' => $billingAddress["addr1"],
'billingAddress2' => $billingAddress["addr2"],
'billingCity' => $billingAddress["city"],
'billingPostcode' => $billingAddress["postcode"],
'billingState' => $billingAddress["county"],
'billingCountry' => $billingCountry,
'shippingFirstName' => $shippingAddress["firstname"],
'shippingLastName' => $shippingAddress["surname"],
'shippingAddress1' => $shippingAddress["addr1"],
'shippingAddress2' => $shippingAddress["addr2"],
'shippingCity' => $shippingAddress["city"],
'shippingPostcode' => $shippingAddress["postcode"],
'shippingState' => $shippingAddress["county"],
'shippingCountry' => $shippingCountry
);
}
public function pay() {
$this->prepareSagePayServer();
$params = array(
"description" => $this->options["description"],
"amount" => $this->calculateAmount(),
"currency" => "GBP",
"returnUrl" => $this->options["confirmURL"],
"transactionId" => $this->transactionID,
"card" => $this->card
);
try {
$response = $this->gateway->purchase($params)->send();
$this->createTransaction($response);
if($response->isSuccessful()) {
// never used
}
else if ($response->isRedirect()) {
$response->redirect();
}
else {
$this->redirectToError();
}
}
catch (Exception $e) {
$this->createTransaction($e);
$this->redirectToError();
}
}
public function confirm() {
$params = array(
"transactionId" => $this->transactionID,
"transactionReference" => $this->retrieveTransactionReference()
);
try {
$response = $this->gateway->completePurchase($params)->send();
$this->updateTransactionStatus($response);
if($response->isSuccessful()) {
$response->confirm($this->options["completeURL"]);
}
else {
$response->confirm($this->options["errorURL"]);
}
}
catch (Exception $e) {
$request = $this->gateway->completePurchase(array());
$response = new \Omnipay\SagePay\Message\ServerCompleteAuthorizeResponse($request, array());
$this->updateTransactionStatus($response);
$this->redirectToError();
}
}
public function complete() {
$transaction = $this->retrieveTransaction();
$this->order->orderComplete($transaction);
}
private function setOptions() {
global $sagepayConfig;
$this->options = $sagepayConfig;
$this->buildURLParameters();
}
private function redirectToError() {
header("Location: " . $this->options["errorURL"]);
exit();
}
private function parseTransactionRef($rawTransactionRef) {
// The implementation is not included here.
return $transactionRef;
}
private function createTransaction($data) {
// The implementation is not included here.
}
private function retrieveTransactionReference() {
// The implementation is not included here.
return $rawTransactionRef;
}
private function retrieveTransaction() {
// The implementation is not included here.
return $transaction;
}
private function createTransactionID() {
if(isset($_GET["transactionid"])) {
$this->transactionID = htmlspecialchars($_GET["transactionid"]);
// test the validity of the transaction id and throw an error if invalid
}
else {
$this->transactionID = $this->order->id . "-" . date("Y-m-d-H-i-s");
}
}
private function updateTransactionStatus($data) {
// The implementation is not included here.
}
private function getStatusUpdates() {
// The implementation is not included here.
return $statusUpdates;
}
private function buildStatusUpdate($newStatus, $statusLog = "[]") {
// The implementation is not included here.
return $statusLog;
}
private function buildURLParameters() {
$urls = array("confirmURL", "completeURL", "errorURL");
$params = array(
"transactionid" => $this->transactionID
);
foreach ($urls as $urlName) {
$url = $this->options[$urlName];
$parsedURL = parse_url($url);
$queries = array();
if(isset($parsedURL["query"])) {
parse_str($parsedURL["query"], $queries);
}
$queries = array_merge($queries, $params);
$parsedURL["query"] = http_build_query($queries);
$this->options[$urlName] = http_build_url($parsedURL);
}
}
private function getCountryISO($countryPrintName) {
// The implementation is not included here.
return $countryISO;
}
private function calculateAmount() {
// The implementation is not included here.
}
}