Skip to content

Commit

Permalink
ideal fast checkout
Browse files Browse the repository at this point in the history
  • Loading branch information
gentiprenaj committed Jan 30, 2025
1 parent f2b4912 commit 79dc3ae
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 181 deletions.
2 changes: 0 additions & 2 deletions src/Handlers/IdealPaymentHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
namespace Buckaroo\Shopware6\Handlers;

use Buckaroo\Shopware6\PaymentMethods\Ideal;
use Buckaroo\Shopware6\Service\CaptureService;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct;
use Symfony\Component\HttpFoundation\RedirectResponse;
class IdealPaymentHandler extends AsyncPaymentHandler
{
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { IdealFastCheckout } from './sdk'; // Importing IdealFastCheckout
import HttpClient from 'src/service/http-client.service';
import Plugin from 'src/plugin-system/plugin.class';
import FormSerializeUtil from 'src/utility/form/form-serialize.util';
export default class IdealFastCheckoutPlugin extends Plugin {

static options = {
Expand All @@ -13,132 +11,102 @@ export default class IdealFastCheckoutPlugin extends Plugin {
cannot_create_payment: "Cannot create the payment. Please try again."
}
}

httpClient = new HttpClient();
url = '/buckaroo';
result = null;
cartToken = null;
httpClient = new HttpClient();
url = '/buckaroo';
result = null;
cartToken = null;

init() {
const element = document.querySelector('[data-buckaroo-ideal-fast-checkout-plugin-options]');

if (element) {
const pluginOptionsData = element.getAttribute('data-buckaroo-ideal-fast-checkout-plugin-options');
if (pluginOptionsData) {
// Step 3: Parse the JSON-encoded options
const options = JSON.parse(pluginOptionsData);
this.options.page = options.page;
console.log(options.containerSelector)
let checkoutButton = document.getElementById('fast-checkout-ideal-btn');
if (!checkoutButton) {
console.error('Ideal Fast Checkout button not found');
return;
}
if (!element) {
console.error('Plugin options element not found');
return;
}

// Using an arrow function to keep the correct `this` context
checkoutButton.addEventListener('click', (e) => {
this.initPayment(e);
});
}
const pluginOptionsData = element.getAttribute('data-buckaroo-ideal-fast-checkout-plugin-options');
if (!pluginOptionsData) {
console.error('No data found in plugin options');
return;
}
const options = JSON.parse(pluginOptionsData);
this.options.page = options.page;

const checkoutButton = document.getElementById('fast-checkout-ideal-btn');
if (!checkoutButton) {
console.error('Ideal Fast Checkout button not found');
return;
}

checkoutButton.addEventListener('click', (e) => this.initPayment(e));
}

initPayment(e) {
e.preventDefault();
this.createCart().then((data) => {
this.createOrder(data);
});
initPayment(event) {
event.preventDefault();
this.createCart();
}

createCart() {
let formData = null;

if (this.options.page === "product") {
const formElement = document.getElementById('productDetailPageBuyProductForm');

formData = FormSerializeUtil.serializeJson(formElement);
let formObject = {};
if (this.options.page === 'product'){
formObject = this.getFormData();
}
if (!formObject) {
console.error('Form data could not be retrieved');
return;
}
return new Promise((resolve, reject) => {
this.httpClient.post(
`${this.url}/ideal/cart/get`,
JSON.stringify({
form: formData,
page: this.options.page,
}),
(response) => {
let resp = JSON.parse(response);
console.log(resp);
if(resp.error) {
this.displayErrorMessage(resp.message);
reject(resp.message);
} else {
this.cartToken = resp.cartToken;
resolve(resp);
}

}
);
return this.sendPostRequest(`${this.url}/idealfastcheckout/pay`, {
form: formObject,
page: this.options.page
}).then(response => {
console.log(response)
if (response.redirect) {
window.location = response.redirect;
return { errors: [] };
} else {
const message = response.message || this.options.i18n.cannot_create_payment;
this.displayErrorMessage(message);
return { status: 'FAILED', errors: [message] };
}
}).catch(error => {
console.error('Error creating cart:', error);
});
}


getFormData() {
const formElement = document.getElementById('productDetailPageBuyProductForm');

/**
* Create the sw6 order with the payment data
* @param {*} payment
*/
createOrder(payment) {
return new Promise((resolve) => {
this.httpClient.post(
`${this.url}/ideal/order/create`,
JSON.stringify({
payment: JSON.stringify(payment),
cartToken: this.cartToken,
page: this.options.page
}),
(response) => {
const resp = JSON.parse(response);
if (resp.redirect) {
resolve({
errors: [],
});
window.location = resp.redirect;
} else {
if (!formElement) {
console.error('Product form not found');
return null;
}

let message = this.options.i18n.cannot_create_payment;
if(resp.message) {
message = resp.message;
}
this.displayErrorMessage(message);
resolve({
status: ApplePaySession.STATUS_FAILURE,
errors: [message],
});
}
}
);
const formData = new FormData(formElement);
const formObject = {};
formData.forEach((value, key) => {
formObject[key] = value;
});
return formObject;
}
onShippingChangeHandler(data, actions) {
const formData = FormSerializeUtil.serializeJson(this.el.closest('form'));
sendPostRequest(url, data) {
return new Promise((resolve, reject) => {
this.httpClient.post(
`${this.url}/idealfastcheckout/updateShipping`,
JSON.stringify({ form: formData, customer: data }),
url,
JSON.stringify(data),
(response) => {
const updatedData = JSON.parse(response);
if (!updatedData.error) {
return actions.order.patch([
{ op: 'replace', path: '/amount', value: updatedData.newAmount }
]);
} else {
reject('Failed to update shipping');
try {
const parsedResponse = JSON.parse(response);
resolve(parsedResponse);
} catch (error) {
console.error('Error parsing response:', error);
reject(error);
}
}
);
});
}

displayErrorMessage(message) {
const errorContainer = document.createElement('div');
errorContainer.className = 'buckaroo-idealfastcheckout-express-error alert alert-warning alert-has-icon';
Expand All @@ -152,9 +120,7 @@ export default class IdealFastCheckoutPlugin extends Plugin {
const flashbags = document.querySelector('.flashbags');
if (flashbags) {
flashbags.prepend(errorContainer);
setTimeout(() => {
errorContainer.remove();
}, 10000);
setTimeout(() => errorContainer.remove(), 10000);
}
}
}
24 changes: 0 additions & 24 deletions src/Resources/app/storefront/src/ideal-fast-checkout/sdk.js

This file was deleted.

6 changes: 6 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@
<argument type="service" id="order.repository"/>
<argument type="service" id="Symfony\Contracts\EventDispatcher\EventDispatcherInterface"/>
<argument type="service" id="Shopware\Core\Checkout\Payment\Cart\PaymentTransactionChainProcessor"/>
<argument type="service" id="Symfony\Component\Routing\Generator\UrlGeneratorInterface"/>
</service>


Expand Down Expand Up @@ -552,5 +553,10 @@
id="Buckaroo\Shopware6\Storefront\Framework\Cookie\BuckarooCookieProvider.inner" />
</service>

<service id="Buckaroo\Shopware6\Subscribers\OrderPlacedSubscriber">
<argument type="service" id="Buckaroo\Shopware6\Service\CartService"/>
<tag name="kernel.event_subscriber"/>
</service>

</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,32 @@
</div>
{% endif %}

{% if page.extensions.buckaroo.showIdealFastCheckout %}
<div class="col-12 p-0">
{% set idealFastCheckoutConfig = {
page: "product",
websiteKey: page.extensions.buckaroo.websiteKey,
i18n: {
cancel_error_message: "buckaroo.checkout.cancelOrderMessage"|trans|sw_sanitize,
cannot_create_payment :"buckaroo.checkout.cannotCreatePayment"|trans|sw_sanitize
}
} %}
<div data-bk-ideal-fast-checkout data-buckaroo-ideal-fast-checkout-plugin-options='{{ idealFastCheckoutConfig|json_encode }}'>
<div class="bk-ideal-fast-checkout" id="fast-checkout-ideal-btn" style="">
<img
src="{{ asset("bundles/buckaroopayments/storefront/buckaroo/#{page.extensions.buckaroo.idealFastCheckoutLogo}.png")}}"
alt="Ideal Snel bestellen"
/>
</div>
</div>
</div>
<script>
document.getElementById('fast-checkout-ideal-btn').addEventListener('click', function() {
window.PluginManager.getPluginInstanceFromElement(document.querySelector('.bk-ideal-fast-checkout'), 'IdealFastCheckoutPlugin');
});
</script>
{% endif %}



{% endblock %}
14 changes: 14 additions & 0 deletions src/Service/CartService.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public function __construct(

public function load(string $token): Cart
{

$this->validateSaleChannelContext();
return $this->cartPersister->load($token, $this->salesChannelContext);
}
Expand All @@ -80,7 +81,9 @@ public function load(string $token): Cart
*/
public function setSaleChannelContext(SalesChannelContext $salesChannelContext): self
{

$this->salesChannelContext = $salesChannelContext;

return $this;
}

Expand Down Expand Up @@ -150,4 +153,15 @@ public function calculateCart(Cart $cart, SalesChannelContext $salesChannelConte
{
return $this->cartCalculator->calculate($cart, $salesChannelContext);
}

/**
* Validate saleChannelContext
*
* @return void
*/
public function deleteFromCart(SalesChannelContext $salesChannelContext): void
{
$token = $salesChannelContext->getToken();
$this->cartPersister->delete($token, $salesChannelContext);
}
}
26 changes: 25 additions & 1 deletion src/Service/OrderService.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,20 @@ public function place(OrderEntity $orderEntity, RequestDataBag $data)
*/
public function doPayment(string $orderId, RequestDataBag $data): ?string
{
$urls = $this->getCheckoutUrls($orderId, $data);

$response = $this->paymentProcessor->process($orderId, $data, $this->salesChannelContext);
// Extract the URLs if available
$finishUrl = $urls['finishUrl'] ?? null;
$errorUrl = $urls['errorUrl'] ?? null;

$response = $this->paymentProcessor->process($orderId, $data, $this->salesChannelContext, $finishUrl, $errorUrl);

if ($response instanceof RedirectResponse) {
return $response->getTargetUrl();
}
return null;
}

/**
* Create order from cart
*
Expand Down Expand Up @@ -166,4 +172,22 @@ private function validateSaleChannelContext()
throw new CreateCartException('SaleChannelContext is required');
}
}
/**
* Get finish and error URLs for the payment process
*
* @param string $orderId
* @param RequestDataBag $data
* @return array|null
*/
private function getCheckoutUrls(string $orderId, RequestDataBag $data): ?array
{
if ($data->get('idealFastCheckoutInfo')) {
return [
'finishUrl' => '/checkout/finish?orderId=' . $orderId,
'errorUrl' => '/account/order/edit/' . $orderId,
];
}

return null;
}
}
Loading

0 comments on commit 79dc3ae

Please sign in to comment.