Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom id passed to PayPal as JSON with additional versioning data #363

Merged
merged 7 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- Catch possible thrown Error by getting DataClientToken
- [0007719](https://bugs.oxid-esales.com/view.php?id=7719): Tracking code also be stored in standard DB field for backwards compatibility
- add possibility to ignore cached tokens. It helps e.g. for webhook registration
- use PayPal-Client v2.0.17

### NEW

- Custom id passed to PayPal as JSON with additional versioning data

## [2.5.1] - 2024-09-20

Expand Down
2 changes: 1 addition & 1 deletion LATEST_CLIENT_TAG
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v2.0.16
v2.0.17
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"giggsey/libphonenumber-for-php": "^8.12",
"viison/address-splitter": "^0.3.4",
"webmozart/path-util": "^2.3.0",
"oxid-solution-catalysts/paypal-client": "v2.0.16"
"oxid-solution-catalysts/paypal-client": "v2.0.17"
},
"require-dev": {
"codeception/module-rest": "^1.4.2",
Expand Down
8 changes: 7 additions & 1 deletion metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
'en' => 'Use of the online payment service from PayPal. Documentation: <a href="https://docs.oxid-esales.com/modules/paypal-checkout/en/latest/" target="_blank">PayPal Checkout</a>'
],
'thumbnail' => 'out/img/paypal.png',
'version' => '2.5.2-rc.1',
'version' => '2.5.2-rc.2',
'author' => 'OXID eSales AG',
'url' => 'https://www.oxid-esales.com',
'email' => '[email protected]',
Expand Down Expand Up @@ -570,5 +570,11 @@
'value' => 3.5,
'group' => null
],
[
'name' => 'oscPayPalUseStructuralCustomIdSchema',
'type' => 'bool',
'value' => false,
'group' => null
],
],
];
3 changes: 3 additions & 0 deletions src/Controller/Admin/PayPalConfigController.php
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ protected function handleSpecialFields(array $conf): array
$dAmount = (string) str_replace(',', '.', $conf['oscPayPalDefaultShippingPriceExpress']);
$conf['oscPayPalDefaultShippingPriceExpress'] = $dAmount;
}
if (!isset($conf['oscPayPalUseStructuralCustomIdSchema'])) {
$conf['oscPayPalUseStructuralCustomIdSchema'] = false;
}
return $conf;
}

Expand Down
5 changes: 5 additions & 0 deletions src/Core/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,11 @@ public function getStartTimeCleanUpOrders(): int
return $this->getServiceFromContainer(ModuleSettings::class)->getStartTimeCleanUpOrders();
}

public function isCustomIdSchemaStructural(): bool
{
return $this->getServiceFromContainer(ModuleSettings::class)->isCustomIdSchemaStructural();
}

public function tableExists(string $tableName = ''): bool
{
$exists = false;
Expand Down
7 changes: 6 additions & 1 deletion src/Core/Onboarding/Webhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use OxidSolutionCatalysts\PayPal\Exception\OnboardingException;
use OxidSolutionCatalysts\PayPal\Service\ModuleSettings;
use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer;
use OxidSolutionCatalysts\PayPalApi\Exception\ApiException;
use OxidSolutionCatalysts\PayPalApi\Service\GenericService;

class Webhook
Expand Down Expand Up @@ -119,7 +120,11 @@ public function getAllRegisteredWebhooks(): array
{
/** @var GenericService $notificationService */
$webhookService = Registry::get(ServiceFactory::class)->getWebhookService();
$result = $webhookService->request('GET');
try {
$result = $webhookService->request('GET');
} catch (ApiException $e) {
$result = [];
}

return $result['webhooks'] ?? [];
}
Expand Down
8 changes: 5 additions & 3 deletions src/Core/ServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function getWebhookService(string $uri = ''): GenericService
{
return oxNew(
GenericService::class,
$this->getClient(),
$this->getClient(false),
'/v1/notifications/webhooks' . $uri
);
}
Expand Down Expand Up @@ -125,7 +125,7 @@ public function getIdentityService(): IdentityService
*
* @return Client
*/
private function getClient(): Client
private function getClient(bool $useToken = true): Client
{
if ($this->client === null) {
/** @var Config $config */
Expand All @@ -142,12 +142,14 @@ private function getClient(): Client
$paymentId = $session->getVariable('paymentid');
$actionHash = md5($sessionId . $basketId . $paymentId);

$sTokenCacheFileName = $useToken ? $config->getTokenCacheFileName() : '';

$client = new Client(
$logger,
$config->isSandbox() ? Client::SANDBOX_URL : Client::PRODUCTION_URL,
$config->getClientId(),
$config->getClientSecret(),
$config->getTokenCacheFileName(),
$sTokenCacheFileName,
$actionHash,
// must be empty. We do not have the merchant's payerid
//and confirmed by paypal we should not use it for auth and
Expand Down
6 changes: 6 additions & 0 deletions src/Service/ModuleSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -624,11 +624,17 @@ public function getIsVaultingActive(): bool
{
return (bool)$this->getSettingValue('oscPayPalSetVaulting');
}

public function getIsGooglePayDeliveryAddressActive(): bool
{
return (bool)$this->getSettingValue('oscPayPalUseGooglePayAddress');
}

public function isCustomIdSchemaStructural(): bool
{
return (bool)$this->getSettingValue('oscPayPalUseStructuralCustomIdSchema');
}

/**
* @return mixed
*/
Expand Down
34 changes: 29 additions & 5 deletions src/Service/Payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use OxidSolutionCatalysts\PayPal\Exception\PayPalException;
use OxidSolutionCatalysts\PayPal\Exception\UserPhone as UserPhoneException;
use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalOrderModel;
use OxidSolutionCatalysts\PayPal\Module;
use OxidSolutionCatalysts\PayPal\Service\ModuleSettings as ModuleSettingsService;
use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer;
use OxidSolutionCatalysts\PayPalApi\Exception\ApiException;
Expand Down Expand Up @@ -128,7 +129,7 @@ public function doCreatePayPalOrder(
$basket,
$intent,
$userAction,
$order instanceof EshopModelOrder ? $order->getFieldData('oxordernr') : null,
null, //customId is patched in doCapturePayPalOrder (ordernr is unavailable at this point)
$processingInstruction,
$paymentSource,
null,
Expand Down Expand Up @@ -309,18 +310,16 @@ public function doCapturePayPalOrder(
} elseif ($payPalOrder->status !== Constants::PAYPAL_STATUS_COMPLETED) {
$request = new OrderCaptureRequest();
//order number must be resolved before order patching
$shopOrderId = $order->getFieldData('oxordernr');
if (!$shopOrderId) {
if (!$order->hasOrderNumber()){
$order->setOrderNumber();
$shopOrderId = $order->getFieldData('oxordernr');
}

try {
//Patching the order with OXID order number as custom value
$this->doPatchPayPalOrder(
Registry::getSession()->getBasket(),
$checkoutOrderId,
$shopOrderId
$this->getCustomIdParameter($order)
);

/** @var $result ApiOrderModel */
Expand Down Expand Up @@ -808,4 +807,29 @@ private function displayErrorIfInstrumentDeclined(?string $issue): void
);
}
}

/**
* @param \OxidEsales\Eshop\Application\Model\Order|null $order
* @return mixed|null
*/
public function getCustomIdParameter(?EshopModelOrder $order): string
{
/** @var ModuleSettingsService $moduleSettings */
$moduleSettings = $this->getServiceFromContainer(ModuleSettings::class);
$module = oxNew(\OxidEsales\Eshop\Core\Module\Module::class);
$module->load(Module::MODULE_ID);
$orderNumber = $order instanceof EshopModelOrder ? $order->getFieldData('oxordernr') : null;

if($moduleSettings->isCustomIdSchemaStructural()){
$customID = [
'oxordernr' => $orderNumber,
'moduleVersion' => $module->getInfo('version'),
'oxidVersion' => \OxidEsales\Eshop\Core\ShopVersion::getVersion()
];

return json_encode($customID);
}

return $orderNumber;
}
}
3 changes: 3 additions & 0 deletions views/admin/de/admin_lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,7 @@

// PayPal Payment
'OSC_PAYPAL_PAYMENT_DEPRECATED' => 'Diese PayPal Zahlungsart kann nicht mehr aktiviert werden, da diese demnächst entfernt wird!',

'OSC_PAYPAL_CUSTOM_ID_CONTENTS_TITLE' => 'PayPal Inhalte des benutzerdefinierten ID-Feldes',
'OSC_PAYPAL_CUSTOM_ID_CONTENTS_DESC' => 'Das benutzerdefinierte PayPal-ID-Feld kann entweder nur den Bestellnummernwert oder ein JSON mit zusätzlichen Daten enthalten.',
];
3 changes: 3 additions & 0 deletions views/admin/en/admin_lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,7 @@

// PayPal Payment
'OSC_PAYPAL_PAYMENT_DEPRECATED' => 'This PayPal payment method can no longer be activated as it will be removed soon!',

'OSC_PAYPAL_CUSTOM_ID_CONTENTS_TITLE' => 'PayPal custom id field contents',
'OSC_PAYPAL_CUSTOM_ID_CONTENTS_DESC' => 'PayPal custom id field will be JSON encoded string with order number, shop version and the PayPal module version.',
];
22 changes: 22 additions & 0 deletions views/admin/tpl/oscpaypalconfig.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,28 @@
</div>
</div>
</div>

<div class="card">
<div class="card-header" id="heading11">
<h4 class="collapsed" data-toggle="collapse" data-target="#collapse11" aria-expanded="false" aria-controls="collapse11">
[{oxmultilang ident="OSC_PAYPAL_CUSTOM_ID_CONTENTS_TITLE"}]
</h4>
</div>
<div id="collapse11" class="collapse" aria-labelledby="heading11" data-parent="#accordion">
<div class="card-body">
<div class="form-group">
<div class="controls">
<div class="form-group">
<div class="controls">
<input type="checkbox" name="conf[oscPayPalUseStructuralCustomIdSchema]" value="1" [{if $config->isCustomIdSchemaStructural()}] checked[{/if}]>
<span class="help-block">[{oxmultilang ident="OSC_PAYPAL_CUSTOM_ID_CONTENTS_DESC"}]</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
[{*
<div class="card">
<div class="card-header" id="heading9">
Expand Down
Loading