Skip to content
1 change: 1 addition & 0 deletions src/Constants/AdditionalTransactionDataKeys.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ class AdditionalTransactionDataKeys
public const CHECKOUTTYPE = 'checkoutType';

public const CARD = 'card';
public const WERO = 'wero';
}
2 changes: 2 additions & 0 deletions src/Constants/IdStrings.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class IdStrings
public const SOFORT = 'sft';
public const TWINT = 'twt';
public const WECHATPAY = 'wcp';
public const WERO = 'wro';

public const OPEN_BANKING = 'obp';

Expand Down Expand Up @@ -95,6 +96,7 @@ class IdStrings
self::SOFORT,
self::TWINT,
self::WECHATPAY,
self::WERO,
self::OPEN_BANKING,
];
}
12 changes: 12 additions & 0 deletions src/Constants/WeroAmountPaymentTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace UnzerSDK\Constants;

/**
* Allowed amount payment type values for Wero event-dependent payment.
*/
class WeroAmountPaymentTypes
{
public const PAY = 'PAY';
public const PAYUPTO = 'PAYUPTO';
}
15 changes: 15 additions & 0 deletions src/Constants/WeroCaptureTriggers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace UnzerSDK\Constants;

/**
* Allowed capture trigger values for Wero event dependent payment.
*/
class WeroCaptureTriggers
{
public const SHIPPING = 'SHIPPING';
public const DELIVERY = 'DELIVERY';
public const AVAILABILITY = 'AVAILABILITY';
public const SERVICEFULFILMENT = 'SERVICEFULFILMENT';
public const OTHER = 'OTHER';
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace UnzerSDK\Resources\EmbeddedResources\Paypage;

use UnzerSDK\Resources\AbstractUnzerResource;
use UnzerSDK\Resources\EmbeddedResources\WeroEventDependentPayment;

class PaymentMethodConfig extends AbstractUnzerResource
{
Expand All @@ -15,6 +16,19 @@ class PaymentMethodConfig extends AbstractUnzerResource
protected ?bool $credentialOnFile = null; // card only.
protected ?string $exemption = null; // card only.

protected ?WeroEventDependentPayment $eventDependentPayment = null;

public function getEventDependentPayment(): ?WeroEventDependentPayment
{
return $this->eventDependentPayment;
}

public function setEventDependentPayment(?WeroEventDependentPayment $eventDependentPayment): PaymentMethodConfig
{
$this->eventDependentPayment = $eventDependentPayment;
return $this;
}

/**
* @param bool|null $enabled
* @param int|null $order
Expand Down Expand Up @@ -80,4 +94,4 @@ public function setExemption(?string $exemption): PaymentMethodConfig
$this->exemption = $exemption;
return $this;
}
}
}
70 changes: 70 additions & 0 deletions src/Resources/EmbeddedResources/WeroEventDependentPayment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace UnzerSDK\Resources\EmbeddedResources;

use UnzerSDK\Constants\WeroAmountPaymentTypes;
use UnzerSDK\Constants\WeroCaptureTriggers;
use UnzerSDK\Resources\AbstractUnzerResource;

/**
* Represents the `eventDependentPayment` object for Wero additional transaction data.
*/
class WeroEventDependentPayment extends AbstractUnzerResource
{
/** @see WeroCaptureTriggers */
protected ?string $captureTrigger = null;
/** @see WeroAmountPaymentTypes */
protected ?string $amountPaymentType = null;
protected ?int $maxAuthToCaptureTime = null;
protected ?bool $multiCapturesAllowed = null;
Comment on lines +15 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it maybe make sense to set some default values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not for now. If we have default values we want to use, i can update that later


public function getCaptureTrigger(): ?string
{
return $this->captureTrigger;
}

/**
* @see WeroCaptureTriggers for allowed values
*/
public function setCaptureTrigger(?string $captureTrigger): WeroEventDependentPayment
{
$this->captureTrigger = $captureTrigger;
return $this;
}

public function getAmountPaymentType(): ?string
{
return $this->amountPaymentType;
}

/**
* @see WeroAmountPaymentTypes for allowed values
*/
public function setAmountPaymentType(?string $amountPaymentType): WeroEventDependentPayment
{
$this->amountPaymentType = $amountPaymentType;
return $this;
}

public function getMaxAuthToCaptureTime(): ?int
{
return $this->maxAuthToCaptureTime;
}

public function setMaxAuthToCaptureTime(?int $maxAuthToCaptureTime): WeroEventDependentPayment
{
$this->maxAuthToCaptureTime = $maxAuthToCaptureTime;
return $this;
}

public function getMultiCapturesAllowed(): ?bool
{
return $this->multiCapturesAllowed;
}

public function setMultiCapturesAllowed(?bool $multiCapturesAllowed): WeroEventDependentPayment
{
$this->multiCapturesAllowed = $multiCapturesAllowed;
return $this;
}
}
48 changes: 48 additions & 0 deletions src/Resources/EmbeddedResources/WeroTransactionData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace UnzerSDK\Resources\EmbeddedResources;

use stdClass;
use UnzerSDK\Adapter\HttpAdapterInterface;
use UnzerSDK\Resources\AbstractUnzerResource;

/*
Copy link

Copilot AI Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use proper PHPDoc format with /** instead of /* for class documentation comments.

Suggested change
/*
/**

Copilot uses AI. Check for mistakes.
* Represents `wero` object of `additionalTransactionData`.
*/

class WeroTransactionData extends AbstractUnzerResource
{
/** @var WeroEventDependentPayment|null $eventDependentPayment */
protected ?WeroEventDependentPayment $eventDependentPayment = null;

/**
* @return WeroEventDependentPayment|null
*/
public function getEventDependentPayment(): ?WeroEventDependentPayment
{
return $this->eventDependentPayment;
}

/**
* @param WeroEventDependentPayment|null $eventDependentPayment
* @return WeroTransactionData
*/
public function setEventDependentPayment(?WeroEventDependentPayment $eventDependentPayment): WeroTransactionData
{
$this->eventDependentPayment = $eventDependentPayment;
return $this;
}

/**
* @inheritDoc
*/
public function handleResponse($response, string $method = HttpAdapterInterface::REQUEST_GET): void
{
parent::handleResponse($response, $method);
if ($response instanceof stdClass && isset($response->eventDependentPayment)) {
$edp = $this->getEventDependentPayment() ?? new WeroEventDependentPayment();
$edp->handleResponse($response->eventDependentPayment);
$this->setEventDependentPayment($edp);
}
}
}
7 changes: 7 additions & 0 deletions src/Resources/PaymentTypes/Wero.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace UnzerSDK\Resources\PaymentTypes;

class Wero extends BasePaymentType
{
}
23 changes: 21 additions & 2 deletions src/Resources/TransactionTypes/AbstractTransactionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@

namespace UnzerSDK\Resources\TransactionTypes;

use RuntimeException;
use stdClass;
use UnzerSDK\Adapter\HttpAdapterInterface;
use UnzerSDK\Exceptions\UnzerApiException;
use UnzerSDK\Resources\AbstractUnzerResource;
use UnzerSDK\Resources\EmbeddedResources\CardTransactionData;
use UnzerSDK\Resources\EmbeddedResources\RiskData;
use UnzerSDK\Resources\EmbeddedResources\ShippingData;
use UnzerSDK\Resources\EmbeddedResources\WeroTransactionData;
use UnzerSDK\Resources\Payment;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Traits\HasAdditionalTransactionData;
Expand All @@ -24,8 +27,6 @@
use UnzerSDK\Traits\HasStates;
use UnzerSDK\Traits\HasTraceId;
use UnzerSDK\Traits\HasUniqueAndShortId;
use RuntimeException;
use stdClass;

abstract class AbstractTransactionType extends AbstractUnzerResource
{
Expand Down Expand Up @@ -170,6 +171,7 @@ protected function handleAdditionalTransactionData(stdClass $response): void
$this->handleRiskData($additionalTransactionData);
$this->handleShipping($additionalTransactionData);
$this->handleCardTransactionData($additionalTransactionData);
$this->handleWeroTransactionData($additionalTransactionData);
}
}

Expand Down Expand Up @@ -223,4 +225,21 @@ protected function handleCardTransactionData(stdClass $additionalTransactionData
$this->setCardTransactionData($cardTransactionData);
}
}

/**
* Handle WeroTransactionData object contained in additional transaction data from API response.
*
* @param stdClass $additionalTransactionData
*
* @return void
*/
protected function handleWeroTransactionData(stdClass $additionalTransactionData): void
{
$wero = $additionalTransactionData->wero ?? null;
if ($wero !== null) {
$weroTransactionData = $this->getWeroTransactionData() ?? new WeroTransactionData();
$weroTransactionData->handleResponse($wero);
$this->setWeroTransactionData($weroTransactionData);
}
}
}
4 changes: 4 additions & 0 deletions src/Services/ResourceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
use UnzerSDK\Resources\PaymentTypes\Sofort;
use UnzerSDK\Resources\PaymentTypes\Twint;
use UnzerSDK\Resources\PaymentTypes\Wechatpay;
use UnzerSDK\Resources\PaymentTypes\Wero;
use UnzerSDK\Resources\Recurring;
use UnzerSDK\Resources\TransactionTypes\Authorization;
use UnzerSDK\Resources\TransactionTypes\Cancellation;
Expand Down Expand Up @@ -957,6 +958,9 @@ public static function getTypeInstanceFromIdString($typeId): BasePaymentType
case IdStrings::WECHATPAY:
$paymentType = new Wechatpay();
break;
case IdStrings::WERO:
$paymentType = new Wero();
break;
case IdStrings::OPEN_BANKING:
$paymentType = new OpenbankingPis();
break;
Expand Down
26 changes: 26 additions & 0 deletions src/Traits/HasAdditionalTransactionData.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use UnzerSDK\Resources\EmbeddedResources\CardTransactionData;
use UnzerSDK\Resources\EmbeddedResources\RiskData;
use UnzerSDK\Resources\EmbeddedResources\ShippingData;
use UnzerSDK\Resources\EmbeddedResources\WeroTransactionData;
use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\TransactionTypes\AbstractTransactionType;
use UnzerSDK\Services\ResourceService;
Expand Down Expand Up @@ -221,4 +222,29 @@ public function setCardTransactionData(?CardTransactionData $cardTransactionData
$this->addAdditionalTransactionData(AdditionalTransactionDataKeys::CARD, $cardTransactionData);
return $this;
}

/**
* Get the wero field from additional transaction Data.
*
* @return WeroTransactionData|null "wero" object of additionalTransaction data.
*/
public function getWeroTransactionData(): ?WeroTransactionData
{
$key = AdditionalTransactionDataKeys::WERO;
$wero = $this->getAdditionalTransactionData()->$key ?? null;
return $wero instanceof WeroTransactionData ? $wero : null;
}

/**
* Sets WeroTransactionData object as "wero" field of additionalTransactionData.
*
* @param WeroTransactionData|null $weroTransactionData
*
* @return self
*/
public function setWeroTransactionData(?WeroTransactionData $weroTransactionData): self
{
$this->addAdditionalTransactionData(AdditionalTransactionDataKeys::WERO, $weroTransactionData);
return $this;
}
}
2 changes: 1 addition & 1 deletion test/BasePaymentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public function createCharge($amount = 100.0): Charge
*/
public static function generateRandomId(): string
{
return str_replace('.', '', microtime(true));
return str_replace('.', '', microtime(true)) . random_int(1000, 9999);
}

/**
Expand Down
19 changes: 12 additions & 7 deletions test/integration/PaymentTypes/PaylaterInstallmentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@
namespace UnzerSDK\test\integration\PaymentTypes;

use UnzerSDK\Constants\CustomerTypes;
use UnzerSDK\Constants\ShippingTypes;
use UnzerSDK\Exceptions\UnzerApiException;
use UnzerSDK\Resources\Customer;
use UnzerSDK\Resources\CustomerFactory;
use UnzerSDK\Resources\EmbeddedResources\Address;
use UnzerSDK\Resources\EmbeddedResources\Paylater\InstallmentPlansQuery;
use UnzerSDK\Resources\EmbeddedResources\Paylater\InstallmentPlan;
use UnzerSDK\Resources\EmbeddedResources\Paylater\InstallmentPlansQuery;
Comment on lines 15 to +22
Copy link

Copilot AI Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import statements are not alphabetically ordered. InstallmentPlansQuery should come after InstallmentPlan.

Copilot uses AI. Check for mistakes.
use UnzerSDK\Resources\PaymentTypes\PaylaterInstallment;
use UnzerSDK\Resources\TransactionTypes\Authorization;
use UnzerSDK\Resources\TransactionTypes\Cancellation;
use UnzerSDK\Resources\TransactionTypes\Charge;
use UnzerSDK\test\BaseIntegrationTest;

use function count;

class PaylaterInstallmentTest extends BaseIntegrationTest
Expand Down Expand Up @@ -232,7 +232,7 @@ protected function createAuthorizeTransaction(): Authorization
$ins = new PaylaterInstallment($plans->getId(), $selectedPlan->getNumberOfRates(), 'DE89370400440532013000', 'DE', 'Peter Mustermann');
$this->unzer->createPaymentType($ins);

$customer = $this->getCustomer()->setFirstname('Peter')->setLastname('Mustermann');
$customer = $this->getCustomer();
$basket = $this->createBasket();

$authorization = new Authorization(99.99, 'EUR', self::RETURN_URL);
Expand All @@ -244,17 +244,22 @@ protected function createAuthorizeTransaction(): Authorization
*/
public function getCustomer(): Customer
{
$customer = CustomerFactory::createCustomer('Manuel', 'Weißmann');
$customer = CustomerFactory::createCustomer('Maximilian', 'Mustermann');
$address = (new Address())
->setStreet('Hugo-Junckers-Straße 3')
->setName('Maximilian Mustermann')
->setStreet('Hugo-Junkers-Str. 3')
->setState('DE-BO')
->setZip('60386')
->setCity('Frankfurt am Main')
->setCountry('DE');
$customer
->setSalutation('mr')
->setBillingAddress($address)
->setBirthDate('2000-12-12')
->setEmail('manuel-weissmann@unzer.com');
->setCustomerId('c' . substr(self::generateRandomId(), 0, 7))
->setShippingAddress((clone $address)->setShippingType(ShippingTypes::EQUALS_BILLING))
->setLanguage('de')
->setBirthDate('1974-10-02')
->setEmail('accept@unzer.com');

return $customer;
}
Expand Down
Loading