Skip to content
This repository has been archived by the owner on Mar 29, 2022. It is now read-only.

Commit

Permalink
Merge pull request #26 from heidelpay/develop
Browse files Browse the repository at this point in the history
PR to release version 1.2.0
  • Loading branch information
Simon Gabriel authored Mar 20, 2019
2 parents 74fa412 + 70b59f9 commit f185287
Show file tree
Hide file tree
Showing 19 changed files with 638 additions and 189 deletions.
13 changes: 8 additions & 5 deletions meta/documents/user_guide_de.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ Dieses Modul stellt einen Container zur Verfügung, der Zahlungsinformationen (z
Um diese Informationen auf der Buchungsbestätigungs-Seite darzustellen folgen Sie bitte folgenden Schritten.
1. wechseln Sie im Backend auf den Menüpunkt *CMS > Container-Verknüpfungen*
2. wählen Sie im Drop-Down-Menü das Plug-in Set, für welches Sie die Änderung vornehmen möchten aus
3. klappen Sie das Menü *Invoice Details (Heidelpay)* auf und aktivieren hier den Ceres-Container ``Order confirmation: Additional payment information``
4. klicken Sie den speichern Button
3. klappen Sie das Menü *Invoice Details (Heidelpay)* auf
4. aktivieren sie den Ceres-Container ``Order confirmation: Additional payment information``
5. klicken Sie den speichern Button

![Container-Verknüpfung](../images/preview_4.png)

## Beschreibung der Zahlungsabläufe
Expand All @@ -133,15 +135,16 @@ Wenn die Zahlung erfolgreich ist, wird die Bestellung im Backend direkt als beza
Wenn die Zahlung fehlschlägt, wird die Bestellung nicht erzeugt und der Kunde wird wieder auf die Checkout-Seite des Shops geleitet.

### Gesicherter Rechnungskauf B2C
Um die Sicherung zu aktivieren müssen Sie im hIP eine Finalisierung (FIN) ausführen.\
* Um die Sicherung zu aktivieren müssen Sie im hIP eine Finalisierung (FIN) ausführen.\
Ab diesem Zeitpunkt startet der vertraglich festgelegte Versicherungzeitraum innerhalb dessen die Zahlung durch den Kunden erwartet wird.\
Wenn der Kunde die Überweisung tätigt erscheint diese im hIP als Receipt (REC) und wird an die Push-URL ihres Shops gesendet.\
* Wenn der Kunde die Überweisung tätigt erscheint diese im hIP als Receipt (REC) und wird an die Push-URL ihres Shops gesendet.\
Hier wird daraufhin eine Zahlung angelegt und mit der Buchung verknüpft.
* Die Überweisungsinformationen werden automatisch beim Erstellen auf die PDF-Rechnung gedruckt.

### Alle Zahlarten
* Zahlungen im Plenty-Backend enthalten die txnId (heidelpay Bestellnummer), die shortId (die eindeutige id der Transaktion d. h. Receipt, Debit oder Capture) und den Hinweis, dass es sich um eine durch heidelpay angelegte Zahlung handelt.
* Im Falle eines Fehlers, der dazu führt, dass die Bestellung im Plenty-Backend nicht angelegt werden kann, während die Zahlung erfolgreich im heidelpay backend erzeugt wird, wird der Buchungstext der Zahlung um eine entsprechende Fehlermeldung erweitert.

## Technische Besonderheiten
* Leider ist es nicht möglich die Bestellung im Nachhinein zu erzeugen, d. h. wenn zum Beispiel die Rückleitung in den Shop nach dem Bezahlen schief geht. Auch wenn die Zahlung erfolgreich im heidelpay backend gespeichert worden ist.\
Durch die Fehlermeldung im Buchungstext von Zahlungen, die nicht zugeordnet werden konnten, ist es möglich diese Fehlerfälle zu erkennen und zu behandeln.
Durch die Fehlermeldung im Buchungstext von Zahlungen, die nicht zugeordnet werden konnten, ist es möglich diese Fehlerfälle zu erkennen und zu behandeln.
15 changes: 9 additions & 6 deletions meta/documents/user_guide_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ This modul provides for a data container to render additional payment informatio
To show the information on your order confirmation page please follow these steps:
1. switch to the menu item *CMS > Container Links*
2. choose the corresponding plug-in set from the drop down
3. open the menu *Invoice Details (Heidelpay)* and enable the ceres container ``Order confirmation: Additional payment information``
4. click the save button
3. open the menu *Invoice Details (Heidelpay)*
4. enable the ceres container ``Order confirmation: Additional payment information``
5. click the save button

![Container links](../images/preview_4.png)

## Workflow description
Expand All @@ -135,16 +137,17 @@ If the payment is successful, the order is immediately marked paid in your backe
If the payment fails, the order is not created and the customer will be redirected to the checkout page.

### Invoice secured B2C
In order to start the insurance of a Payment you need to trigger a finalize transaction (FIN) from the hIP.\
* In order to start the insurance of a Payment you need to trigger a finalize transaction (FIN) from the hIP.\
This starts the insurance period in which the customer has to transfert the total amount of the order.\
This period is determined within your contract with heidelpay.\
As soon as the customer transferred the total amount a receipt transaction (REC) appears within the hIP and is sent to the pushUrl of your shop.\
* This period is determined within your contract with heidelpay.\
As soon as the customer transferred the total amount a receipt transaction (REC) appears within the hIP and is sent to the pushUrl of your shop.
The shop module will then create a new payment and link it to the corresponding order.
* The bank information for the customer will be written on the invoice pdf automatically on creation.

### All payment methods
* Payments contain the txnId (which is the heidelpay orderId), the shortId (the id of the transaction which lead to the payment i.e. Receipt, Debit or Capture) and the origin (i.e. heidelpay).
* In case of an error resulting in the order not being created while the payment has been successful will lead to an unassigned plenty payment with the error message prepended to the booking text.

## Known Issues
* Unfortunately there is no way for us to create the order if the initial order creation fails, even if the payment has been successfully booked in our backend.\
However you will be able to tell there has been an error when there are unassigned payments in your plenty backend showing an error in the booking text.
However you will be able to tell there has been an error when there are unassigned payments in your plenty backend showing an error in the booking text.
3 changes: 2 additions & 1 deletion resources/lang/de/payment.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ errorBookingTextIsMissing = "PaymentProperty::TYPE_BOOKING_TEXT ist nicht gesetz
errorTransactionTypeUndefined = "Transaction type ist nicht definiert"
debugPaymentFound = "Plenty Payment gefunden"
debugHandleIncomingPayment = "Eingehende Zahlungsinformationen wird verarbeitet."
warningOrderDoesNotExist = "Die Bestellung existiert (noch) nicht."
warningOrderDoesNotExist = "Die Bestellung existiert (noch) nicht."
addressesShouldMatch = "Rechnungs- und Versandadresse müssen gleich sein."
3 changes: 2 additions & 1 deletion resources/lang/en/payment.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ errorBookingTextIsMissing = "PaymentProperty::TYPE_BOOKING_TEXT is not set"
errorTransactionTypeUndefined = "Transaction type is undefined"
debugPaymentFound = "Plenty Payment found"
debugHandleIncomingPayment = "Handle incoming payment information."
warningOrderDoesNotExist = "Order does not exist (yet)."
warningOrderDoesNotExist = "Order does not exist (yet)."
addressesShouldMatch = "Invoice and shipping address must match."
34 changes: 15 additions & 19 deletions resources/views/content/InvoiceDetails.twig
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
<hr>
<strong>{{ trans("Heidelpay::template.pleaseTransferTheTotalTo") }}</strong>
<div class="row">
<strong class="col-xs-6 col-sm-5">{{ trans("Heidelpay::template.pleaseTransferTheTotalTo") }}</strong>
<span class="col-xs-6 col-sm-7">
<div class="row">
<div class="col-xs-6">{{ trans("Heidelpay::template.accountIban") }}:</div>
<div class="col-xs-6">{{ accountIBAN }}</div>
</div>
<div class="row">
<div class="col-xs-6">{{ trans("Heidelpay::template.accountBic") }}:</div>
<div class="col-xs-6">{{ accountBIC }}</div>
</div>
<div class="row">
<div class="col-xs-6">{{ trans("Heidelpay::template.accountHolder") }}:</div>
<div class="col-xs-6">{{ accountHolder }}</div>
</div>
<div class="row">
<div class="col-xs-6">{{ trans("Heidelpay::template.accountUsage") }}:</div>
<div class="col-xs-6">{{ accountUsage }}</div>
</div>
</span>
<div class="col-xs-6 col-sm-5">{{ trans("Heidelpay::template.accountIban") }}:</div>
<div class="col-xs-6 col-sm-7">{{ accountIBAN }}</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-5">{{ trans("Heidelpay::template.accountBic") }}:</div>
<div class="col-xs-6 col-sm-7">{{ accountBIC }}</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-5">{{ trans("Heidelpay::template.accountHolder") }}:</div>
<div class="col-xs-6 col-sm-7">{{ accountHolder }}</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-5">{{ trans("Heidelpay::template.accountUsage") }}:</div>
<div class="col-xs-6 col-sm-7">{{ accountUsage }}</div>
</div>
10 changes: 5 additions & 5 deletions resources/views/invoiceSecuredB2CForm.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
{% block content %}
<form action="{{ submit_action }}" id="heidelpay-payment-form" method="post">
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-3"></div>
<div class="col-md-2">
<label for="salutation" class="required">{{ trans('Heidelpay::template.salutation') }} <em>*</em></label>
</div>
<div class="col-md-2">
<div class="col-md-3">
<select id="salutation" name="customer_salutation" required>
<option value="" disabled {% if customer_gender == '' %}selected{% endif %}>{{ trans('Heidelpay::template.choose') }}</option>
<option value="MR" {% if customer_gender == 'male' %}selected{% endif %}>{{ trans('Heidelpay::template.mr') }}</option>
Expand All @@ -17,7 +17,7 @@
<div class="col-md-4"></div>
</div>
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-3"></div>
<div class="col-md-2">
<label for="dateofbirth" class="required">{{ trans('Heidelpay::template.birthday') }} <em>*</em></label>
</div>
Expand Down Expand Up @@ -64,11 +64,11 @@
</select>
</div>
</div>
<div class="col-md-3"></div>
<div class="col-md-4"></div>
</div>
{% include "Heidelpay::partials/cancelSubmitButtons" %}
</form>
{% endblock %}

{% block scripts %}
{% endblock %}
{% endblock %}
123 changes: 83 additions & 40 deletions src/Helper/PaymentHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@
use Heidelpay\Methods\InvoiceSecuredB2C;
use Heidelpay\Methods\PaymentMethodContract;
use Heidelpay\Methods\Sofort;
use Heidelpay\Models\Contracts\OrderTxnIdRelationRepositoryContract;
use Heidelpay\Models\Contracts\TransactionRepositoryContract;
use Heidelpay\Models\OrderTxnIdRelation;
use Heidelpay\Models\Transaction;
use Heidelpay\Services\ArraySerializerService;
use Plenty\Modules\Authorization\Services\AuthHelper;
use Heidelpay\Services\OrderServiceContract;
use Plenty\Modules\Basket\Events\Basket\AfterBasketChanged;
use Plenty\Modules\Basket\Events\Basket\AfterBasketCreate;
use Plenty\Modules\Basket\Events\BasketItem\AfterBasketItemAdd;
use Plenty\Modules\Frontend\Events\FrontendLanguageChanged;
use Plenty\Modules\Frontend\Events\FrontendShippingCountryChanged;
use Plenty\Modules\Helper\Services\WebstoreHelper;
use Plenty\Modules\Order\Contracts\OrderRepositoryContract;
use Plenty\Modules\Order\Models\Order;
use Plenty\Modules\Payment\Contracts\PaymentOrderRelationRepositoryContract;
use Plenty\Modules\Payment\Contracts\PaymentPropertyRepositoryContract;
Expand Down Expand Up @@ -53,8 +55,6 @@ class PaymentHelper

/** @var PaymentMethodRepositoryContract $paymentMethodRepo */
protected $paymentMethodRepo;
/** @var OrderRepositoryContract */
private $orderRepo;
/** @var PaymentOrderRelationRepositoryContract */
private $paymentOrderRelationRepo;
/** @var MainConfigContract */
Expand All @@ -63,29 +63,43 @@ class PaymentHelper
private $methodConfig;
/** @var PaymentPropertyRepositoryContract */
private $paymentPropertyRepo;
/** @var OrderServiceContract */
private $orderService;
/** @var OrderTxnIdRelationRepositoryContract */
private $orderTxnIdRelationRepo;
/**
* @var TransactionRepositoryContract
*/
private $transactionRepo;

/**
* @param PaymentMethodRepositoryContract $paymentMethodRepo
* @param OrderRepositoryContract $orderRepository
* @param PaymentOrderRelationRepositoryContract $paymentOrderRepo
* @param MainConfigContract $mainConfig
* @param MethodConfigContract $methodConfig
* @param PaymentPropertyRepositoryContract $propertyRepo
* @param OrderServiceContract $orderService
* @param OrderTxnIdRelationRepositoryContract $orderTxnIdRelationRepo
* @param TransactionRepositoryContract $transactionRepo
*/
public function __construct(
PaymentMethodRepositoryContract $paymentMethodRepo,
OrderRepositoryContract $orderRepository,
PaymentOrderRelationRepositoryContract $paymentOrderRepo,
MainConfigContract $mainConfig,
MethodConfigContract $methodConfig,
PaymentPropertyRepositoryContract $propertyRepo
PaymentPropertyRepositoryContract $propertyRepo,
OrderServiceContract $orderService,
OrderTxnIdRelationRepositoryContract $orderTxnIdRelationRepo,
TransactionRepositoryContract $transactionRepo
) {
$this->paymentMethodRepo = $paymentMethodRepo;
$this->orderRepo = $orderRepository;
$this->paymentOrderRelationRepo = $paymentOrderRepo;
$this->mainConfig = $mainConfig;
$this->methodConfig = $methodConfig;
$this->paymentPropertyRepo = $propertyRepo;
$this->orderService = $orderService;
$this->orderTxnIdRelationRepo = $orderTxnIdRelationRepo;
$this->transactionRepo = $transactionRepo;
}

/**
Expand Down Expand Up @@ -287,7 +301,7 @@ public function mapHeidelpayTransactionType(string $paymentCode): string
public function assignPlentyPaymentToPlentyOrder(Payment $payment, int $orderId): Order
{
/** @var Order $order */
$order = $this->getOrder($orderId);
$order = $this->orderService->getOrder($orderId);

$additionalInfo = ['Order' => $order, 'Payment' => $payment];
$this->getLogger(__METHOD__)->debug('Heidelpay::payment.debugAssignPaymentToOrder', $additionalInfo);
Expand Down Expand Up @@ -469,37 +483,6 @@ public function setBookingTextError(Payment $paymentObject, string $bookingError
return $this;
}

/**
* Fetches the Order object to the given orderId.
*
* @param int $orderId
* @return Order
* @throws \RuntimeException
*/
private function getOrder(int $orderId): Order
{
$order = null;

/** @var AuthHelper $authHelper */
$authHelper = pluginApp(AuthHelper::class);

try {// Get the order by the given order ID
$order = $authHelper->processUnguarded(
function () use ($orderId) {
return $this->orderRepo->findOrderById($orderId);
}
);
} catch (\Exception $e) {
// no need to handle here
}

// Check whether the order exists
if (!$order instanceof Order) {
throw new \RuntimeException('payment.warningOrderDoesNotExist');
}
return $order;
}

/**
* Returns the property with of the given type.
*
Expand All @@ -518,4 +501,64 @@ public function getPaymentProperty(Payment $paymentObject, int $typeId): Payment

return null;
}

/**
* Returns an array holding the bank details for the given order.
* The array will be empty when no details are available.
*
* @param Order $order
* @return array
*/
public function getPaymentDetailsForOrder(Order $order): array
{
$relation = $this->orderTxnIdRelationRepo->getOrderTxnIdRelationByOrderId($order->id);

if ($relation instanceof OrderTxnIdRelation) {
return $this->getPaymentDetailsByTxnId($relation->txnId);
}

return [];
}

/**
* Returns an array holding the bank details for the given txnId.
* The array will be empty when no details are available.
*
* @param string $txnId
* @return array
*/
public function getPaymentDetailsByTxnId($txnId): array
{
$transactions = $this->transactionRepo->getTransactionsByTxnId($txnId);
$paymentDetails = [];

foreach ($transactions as $transaction) {
/** @var Transaction $transaction */
if ($transaction->transactionType === TransactionType::AUTHORIZE) {
$details = $transaction->transactionDetails;
if (!isset(
$details['CONNECTOR.ACCOUNT_IBAN'],
$details['CONNECTOR.ACCOUNT_IBAN'],
$details['CONNECTOR.ACCOUNT_IBAN'],
$details['CONNECTOR.ACCOUNT_IBAN']
)) {
break;
}

$accountIBAN = $details['CONNECTOR.ACCOUNT_IBAN'];
$accountBIC = $details['CONNECTOR.ACCOUNT_BIC'];
$accountHolder = $details['CONNECTOR.ACCOUNT_HOLDER'];
$accountUsage = $details['CONNECTOR.ACCOUNT_USAGE'] ?? $transaction->shortId;

$paymentDetails = [
'accountIBAN' => $accountIBAN,
'accountBIC' => $accountBIC,
'accountHolder' => $accountHolder,
'accountUsage' => $accountUsage
];
}
}

return $paymentDetails;
}
}
Loading

0 comments on commit f185287

Please sign in to comment.