Skip to content

Commit

Permalink
OctopusDeploy release: 10.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
securesubmit-buildmaster committed Sep 7, 2023
1 parent 2c01312 commit 7709729
Show file tree
Hide file tree
Showing 38 changed files with 384 additions and 255 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

## Latest Version
#### Enhancements:
- [GP-ECOM] Support parseResponse for status_url on HostedService (HPP APMs)
- [GP-ECOM] Added "custnum" from Customer on "payer_new" request

## v10.0.1 (08/29/2023)
#### Enhancements:
- Enhance logs based on environment (GP-API & GP-ECOM)
- Security vulnerabilities fixes
- [GP-API] Add missing properties to authentication->three_ds (message_version, eci,server_trans_reference,
Expand Down
17 changes: 12 additions & 5 deletions examples/gp-ecom/hpp/get-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@
use GlobalPayments\Api\Services\HostedService;
use GlobalPayments\Api\Entities\Enums\PhoneNumberType;
use GlobalPayments\Api\Entities\Enums\HostedPaymentMethods;
use GlobalPayments\Api\Entities\Enums\AlternativePaymentType;

// configure client, request and HPP settings
$config = new GpEcomConfig();
/* Credentials for OpenBanking HPP
$config->merchantId = "openbankingsandbox";
$config->accountId = "internet";
$config->sharedSecret = "sharedsecret";
*/
$config->merchantId = "heartlandgpsandbox";
$config->accountId = "hpp";
$config->sharedSecret = "secret";
$config->serviceUrl = "https://pay.sandbox.realexpayments.com/pay";
$config->enableBankPayment = true;
$config->hostedPaymentConfig = new HostedPaymentConfig();
Expand All @@ -42,12 +48,13 @@
$hostedPaymentData->notReturnAddress = filter_var($_REQUEST['notReturnAddress'], FILTER_VALIDATE_BOOLEAN);
}

$hostedPaymentData->customerCountry = 'GB';
$hostedPaymentData->customerCountry = 'DE';
$hostedPaymentData->customerFirstName = 'James';
$hostedPaymentData->customerLastName = 'Mason';
$hostedPaymentData->transactionStatusUrl = $_SERVER['HTTP_REFERER'] . '/examples/hpp/response-endpoint.php';
$hostedPaymentData->merchantResponseUrl = $_SERVER['HTTP_REFERER'] . '/examples/hpp/response-endpoint.php';
$hostedPaymentData->presetPaymentMethods = [HostedPaymentMethods::CARDS, HostedPaymentMethods::OB];
$baseUrl = 'https://ff6e-2a02-2f0e-5615-3300-b580-5acb-6bf-4b11.ngrok-free.app';
$hostedPaymentData->transactionStatusUrl = "$baseUrl/examples/gp-ecom/hpp/status-endpoint.php";
$hostedPaymentData->merchantResponseUrl = "$baseUrl/examples/gp-ecom/hpp/response-endpoint.php";
$hostedPaymentData->presetPaymentMethods = [HostedPaymentMethods::CARDS, HostedPaymentMethods::OB, AlternativePaymentType::SOFORTUBERWEISUNG];

$billingAddress = new Address();
$billingAddress->streetAddress1 = "Flat 123";
Expand Down Expand Up @@ -75,7 +82,7 @@

try {
$hppJson = $service->charge(19.99)
->withCurrency("GBP")
->withCurrency("EUR")
->withHostedPaymentData($hostedPaymentData)
->withAddress($billingAddress, AddressType::BILLING)
->withAddress($shippingAddress, AddressType::SHIPPING)
Expand Down
20 changes: 18 additions & 2 deletions examples/gp-ecom/hpp/response-endpoint.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

require_once('../../../autoload_standalone.php');

use GlobalPayments\Api\ServiceConfigs\Gateways\GpEcomConfig;
Expand All @@ -7,9 +11,15 @@

// configure client settings
$config = new GpEcomConfig();
/* Credentials for OpenBanking HPP
$config->merchantId = "openbankingsandbox";
$config->accountId = "internet";
$config->sharedSecret = "sharedsecret";
*/
$config->merchantId = "heartlandgpsandbox";
$config->accountId = "hpp";
$config->sharedSecret = "secret";

$config->serviceUrl = "https://pay.sandbox.realexpayments.com/pay";

$service = new HostedService($config);
Expand All @@ -22,11 +32,17 @@
* '"CARD_PAYMENT_BUTTON":"Place Order","AVSADDRESSRESULT":"M","AVSPOSTCODERESULT":"M","BATCHID":"445196",' .
* '"MESSAGE":"[ test system ] Authorised","PASREF":"15011597872195765","CVNRESULT":"M","HPP_FRAUDFILTER_RESULT":"PASS"}";
*/
$responseJson = isset($_POST['hppResponse']) ? $_POST['hppResponse'] : "";
if (!isset($_REQUEST['hppResponse'])) {
$responseJson = json_encode($_REQUEST);
$encoded = false;
} else {
$responseJson = $_REQUEST['hppResponse'];
$encoded = true;
}

try {
// create the response object from the response JSON
$parsedResponse = $service->parseResponse($responseJson, true);
$parsedResponse = $service->parseResponse($responseJson, $encoded);

$orderId = $parsedResponse->orderId; // GTI5Yxb0SumL_TkDMCAxQA
$responseCode = $parsedResponse->responseCode; // 00
Expand Down
46 changes: 46 additions & 0 deletions examples/gp-ecom/hpp/status-endpoint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

require_once('../../../autoload_standalone.php');

use GlobalPayments\Api\ServiceConfigs\Gateways\GpEcomConfig;
use GlobalPayments\Api\Services\HostedService;
use GlobalPayments\Api\Entities\Exceptions\ApiException;

// configure client settings
$config = new GpEcomConfig();
$config->merchantId = "heartlandgpsandbox";
$config->accountId = "hpp";
$config->sharedSecret = "secret";
$config->serviceUrl = "https://pay.sandbox.realexpayments.com/pay";

$service = new HostedService($config);

/*
* Response JSON comes from Global Payments
* sample response JSON (values will be Base64 encoded):
* $responseJson ='{"MERCHANT_ID":"MerchantId","ACCOUNT":"internet","ORDER_ID":"GTI5Yxb0SumL_TkDMCAxQA","AMOUNT":"1999",' .
* '"TIMESTAMP":"20170725154824","SHA1HASH":"843680654f377bfa845387fdbace35acc9d95778","RESULT":"00","AUTHCODE":"12345",' .
* '"CARD_PAYMENT_BUTTON":"Place Order","AVSADDRESSRESULT":"M","AVSPOSTCODERESULT":"M","BATCHID":"445196",' .
* '"MESSAGE":"[ test system ] Authorised","PASREF":"15011597872195765","CVNRESULT":"M","HPP_FRAUDFILTER_RESULT":"PASS"}";
*/
$responseJson = json_encode($_REQUEST);

try {
// create the response object from the response JSON
$parsedResponse = $service->parseResponse($responseJson);

$orderId = $parsedResponse->orderId; // GTI5Yxb0SumL_TkDMCAxQA
$responseCode = $parsedResponse->responseCode; // 00
$responseMessage = $parsedResponse->responseMessage; // [ test system ] Authorised
$responseValues = $parsedResponse->responseValues; // get values accessible by key
echo "<pre>";
echo "Response Code : " . !empty($responseCode) ? $responseCode : "";
echo "\n Response Message : " . !empty($responseMessage) ? $responseMessage : "";
echo "\n Response Values : ";
if (!empty($responseValues))
print_r($responseValues);
} catch (ApiException $e) {
print_r($e);
// For example if the SHA1HASH doesn't match what is expected
// TODO: add your error handling here
}
2 changes: 1 addition & 1 deletion metadata.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<xml>
<releaseNumber>10.0.1</releaseNumber>
<releaseNumber>10.0.2</releaseNumber>
</xml>
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ private function buildCustomer($xml, $builder)
$payer->appendChild($xml->createElement("surname", $customer->lastName ?? ''));
$payer->appendChild($xml->createElement("company", $customer->company ?? ''));


if ($customer->address != null) {
$address = $xml->createElement("address");
$address->appendChild($xml->createElement("line1", $customer->address->streetAddress1 ?? ''));
Expand All @@ -303,6 +302,7 @@ private function buildCustomer($xml, $builder)

$payer->appendChild($phonenumbers);
$payer->appendChild($xml->createElement("email", $customer->email ?? ''));
$payer->appendChild($xml->createElement("custnum", $customer->id ?? ''));

return $payer;
}
Expand Down
57 changes: 47 additions & 10 deletions src/Services/HostedService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use GlobalPayments\Api\Builders\AuthorizationBuilder;
use GlobalPayments\Api\Builders\ManagementBuilder;
use GlobalPayments\Api\Entities\AlternativePaymentResponse;
use GlobalPayments\Api\Entities\Enums\PaymentMethodType;
use GlobalPayments\Api\Entities\Enums\ShaHashType;
use GlobalPayments\Api\Entities\Enums\TransactionType;
Expand All @@ -13,7 +14,6 @@
use GlobalPayments\Api\Utils\GenerationUtils;
use GlobalPayments\Api\Entities\Exceptions\ApiException;
use GlobalPayments\Api\Entities\Transaction;
use GlobalPayments\Api\ServiceConfigs\ServicesConfig;

class HostedService
{
Expand Down Expand Up @@ -95,12 +95,35 @@ public function void($transaction = null)
->withPaymentMethod($transaction);
}

private function mapTransactionStatusResponse($response) : array
{
return [
'ACCOUNT_HOLDER_NAME' => $response['accountholdername'],
'ACCOUNT_NUMBER' => $response['accountnumber'],
'TIMESTAMP' => $response['timestamp'],
'MERCHANT_ID' => $response['merchantid'],
'BANK_CODE' => $response['bankcode'],
'BANK_NAME' => $response['bankname'],
'HPP_CUSTOMER_BIC' => $response['bic'],
'COUNTRY' => $response['country'],
'HPP_CUSTOMER_EMAIL' => $response['customeremail'],
'TRANSACTION_STATUS' => $response['fundsstatus'],
'IBAN' => $response['iban'],
'MESSAGE' => $response['message'],
'ORDER_ID' => $response['orderid'],
'PASREF' => $response['pasref'],
'PAYMENTMETHOD' => $response['paymentmethod'],
'PAYMENT_PURPOSE' => $response['paymentpurpose'],
'RESULT' => $response['result'],
$this->shaHashType . "HASH" => $response[strtolower($this->shaHashType).'hash']
];
}

public function parseResponse($response, $encoded = false)
{
if (empty($response)) {
throw new ApiException("Enable to parse : empty response");
}

$response = json_decode($response, true);

if ($encoded) {
Expand All @@ -114,17 +137,24 @@ public function parseResponse($response, $encoded = false)
$response = $iterator->getArrayCopy();
}

if (!isset($response['MERCHANT_RESPONSE_URL'])) {
$response = $this->mapTransactionStatusResponse($response);
}

$timestamp = $response["TIMESTAMP"];
$merchantId = $response["MERCHANT_ID"];
$orderId = $response["ORDER_ID"];
$result = $response["RESULT"];
$message = $response["MESSAGE"];
$transactionId = $response["PASREF"];
$authCode = $response["AUTHCODE"];
$authCode = $response["AUTHCODE"] ?? "";
$paymentMethod = $response["PAYMENTMETHOD"] ?? "";

if (empty($response[$this->shaHashType . "HASH"])) {
throw new ApiException("SHA hash is missing. Please check your code and the Developers Documentation.");
}
$shaHash = $response[$this->shaHashType . "HASH"];

$hash = GenerationUtils::generateNewHash(
$this->sharedSecret,
implode('.', [
Expand All @@ -134,7 +164,7 @@ public function parseResponse($response, $encoded = false)
$result,
$message,
$transactionId,
$authCode
!isset($response['MERCHANT_RESPONSE_URL']) ? $paymentMethod :$authCode
]),
$this->shaHashType
);
Expand All @@ -146,20 +176,27 @@ public function parseResponse($response, $encoded = false)
$ref = new TransactionReference();
$ref->authCode = $authCode;
$ref->orderId = $orderId;
$ref->paymentMethodType = PaymentMethodType::CREDIT;
$ref->paymentMethodType = !empty($response['PAYMENTMETHOD']) ? PaymentMethodType::APM : PaymentMethodType::CREDIT;
$ref->transactionId = $transactionId;

$trans = new Transaction();

if (isset($response["AMOUNT"])) {
$trans->authorizedAmount = $response["AMOUNT"];
}
$trans->authorizedAmount = $response["AMOUNT"] ?? null;

$trans->cvnResponseCode = $response["CVNRESULT"];
$trans->cvnResponseCode = $response["CVNRESULT"] ?? null;
$trans->responseCode = $result;
$trans->responseMessage = $message;
$trans->avsResponseCode = $response["AVSPOSTCODERESULT"];
$trans->avsResponseCode = $response["AVSPOSTCODERESULT"] ?? null;
$trans->transactionReference = $ref;
if (!empty($response['PAYMENTMETHOD'])) {
$apm = new AlternativePaymentResponse();
$apm->country = $response['COUNTRY'] ?? '';
$apm->providerName = $response['PAYMENTMETHOD'];
$apm->paymentStatus = $response['TRANSACTION_STATUS'] ?? null;
$apm->reasonCode = $response['PAYMENT_PURPOSE'] ?? null;
$apm->accountHolderName = $response['ACCOUNT_HOLDER_NAME'] ?? null;
$trans->alternativePaymentResponse = $apm;
}

$trans->responseValues = $response;

Expand Down
4 changes: 2 additions & 2 deletions test/Integration/Gateways/GpApiConnector/AccessTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public function testUseOnlyAccessToken()
$this->assertEquals('VERIFIED', $response->responseMessage);
}

private function assertAccessTokenResponse(AccessTokenInfo $accessTokenInfo)
private function assertAccessTokenResponse(AccessTokenInfo $accessTokenInfo): void
{
$this->assertNotNull($accessTokenInfo);
$this->assertNotNull($accessTokenInfo->accessToken);
Expand All @@ -237,7 +237,7 @@ private function assertAccessTokenResponse(AccessTokenInfo $accessTokenInfo)
$this->assertNotNull($accessTokenInfo->dataAccountID);
}

public function setUpConfig()
public function setUpConfig(): GpApiConfig
{
$this->config = BaseGpApiTestConfig::gpApiSetupConfig(Channel::CardNotPresent);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace GlobalPayments\Api\Tests\Integration\Gateways\GpApiConnector\Certifications;
namespace Gateways\GpApiConnector\Certifications;

use GlobalPayments\Api\Entities\Enums\Channel;
use GlobalPayments\Api\Entities\Enums\EmvLastChipRead;
Expand Down Expand Up @@ -42,7 +42,7 @@ public static function tearDownAfterClass(): void
public function testDebitSaleWithChipCondition()
{
$debitCard = new DebitTrackData();
$debitCard->value = ';4024720012345671=18125025432198712345?';
$debitCard->value = ';4024720012345671=30125025432198712345?';
$debitCard->pinBlock = 'AFEC374574FC90623D010000116001EE';
$debitCard->entryMethod = EntryMethod::SWIPE;
$response = $debitCard->charge(100)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Gateways\GpApiConnector;

use DateTime;
use GlobalPayments\Api\Entities\Enums\Channel;
use GlobalPayments\Api\Entities\Enums\EmvLastChipRead;
use GlobalPayments\Api\Entities\Enums\EntryMethod;
Expand Down Expand Up @@ -167,7 +168,7 @@ public function testReauthAReversedAuthorizedTransaction()

public function testReauthorizedAnExistingTransaction()
{
$startDate = (new \DateTime())->modify('-29 days')->setTime(0, 0, 0);
$startDate = (new DateTime())->modify('-29 days')->setTime(0, 0, 0);

$response = ReportingService::findTransactionsPaged(1, 1)
->orderBy(TransactionSortProperty::TIME_CREATED, SortDirection::ASC)
Expand Down Expand Up @@ -747,7 +748,7 @@ public function testIncrementalAuth_TransactionNotFound()
}
}

private function initCreditCardData()
private function initCreditCardData(): CreditCardData
{
$card = new CreditCardData();
$card->number = "5425230000004415";
Expand All @@ -760,7 +761,7 @@ private function initCreditCardData()
return $card;
}

private function initCreditTrackData($entryMethod = EntryMethod::SWIPE)
private function initCreditTrackData($entryMethod = EntryMethod::SWIPE): CreditTrackData
{
$card = new CreditTrackData();
$card->setTrackData('%B4012002000060016^VI TEST CREDIT^251210118039000000000396?;4012002000060016=25121011803939600000?');
Expand All @@ -769,7 +770,7 @@ private function initCreditTrackData($entryMethod = EntryMethod::SWIPE)
return $card;
}

private function assertTransactionResponse($transaction, $transactionResponseCode, $transactionStatus)
private function assertTransactionResponse($transaction, $transactionResponseCode, $transactionStatus): void
{
$this->assertNotNull($transaction);
$this->assertEquals($transactionResponseCode, $transaction->responseCode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ public function testCreditGetDccInfo_WithoutCurrency()
}
}

private function assertDccInfoResponse($dccDetails, $expectedDccValue)
private function assertDccInfoResponse($dccDetails, $expectedDccValue): void
{
$this->assertNotNull($dccDetails);
$this->assertEquals('SUCCESS', $dccDetails->responseCode);
Expand All @@ -325,7 +325,7 @@ private function assertDccInfoResponse($dccDetails, $expectedDccValue)
$this->assertEquals($expectedDccValue, $dccDetails->dccRateData->cardHolderAmount);
}

private function assertTransactionResponse($transaction, $transactionStatus, $expectedDccValue)
private function assertTransactionResponse($transaction, $transactionStatus, $expectedDccValue): void
{
$this->assertNotNull($transaction);
$this->assertEquals('SUCCESS', $transaction->responseCode);
Expand All @@ -335,7 +335,7 @@ private function assertTransactionResponse($transaction, $transactionStatus, $ex
}
}

private function getAmount($dccDetails)
private function getAmount($dccDetails): float
{
return round($this->amount * $dccDetails->dccRateData->cardHolderRate, 2);
}
Expand Down
Loading

0 comments on commit 7709729

Please sign in to comment.