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

Make PayNL compatible with rapidez v3 #21

Merged
merged 5 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"require": {
"php": "^8.1|^8.2",
"justbetter/laravel-magento-client": "^2.1",
"rapidez/core": "^2.8"
"rapidez/core": "^3.0"
},
"config": {
"sort-packages": true
Expand Down
5 changes: 0 additions & 5 deletions config/rapidez/paynl.php

This file was deleted.

139 changes: 64 additions & 75 deletions resources/js/eventlisteners.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,72 @@
import { token } from 'Vendor/rapidez/core/resources/js/stores/useUser'
import { mask } from 'Vendor/rapidez/core/resources/js/stores/useMask'
import { cart } from 'Vendor/rapidez/core/resources/js/stores/useCart'
import { addBeforePaymentMethodHandler, addBeforePlaceOrderHandler, addAfterPlaceOrderHandler } from 'Vendor/rapidez/core/resources/js/stores/usePaymentHandlers'

document.addEventListener('vue:loaded', () => {
async function placeOrder() {
if (!token.value && window.app.guestEmail) {
await window.magentoGraphQL(
`mutation setGuestEmailOnCart($cart_id: String!, $email: String!) {
setGuestEmailOnCart(input: {
cart_id: $cart_id
email: $email
}) {
cart {
email
}
}
}`,
{
cart_id: mask.value,
email: window.app.guestEmail
}
)
}
addBeforePaymentMethodHandler(async function (query, variables, options) {
if (!variables.code.includes('paynl_') || !window?.app?.checkout?.pay_issuer)
{
return [query, variables, options];
}

await window.magentoGraphQL(
`mutation setPaymentMethodOnCart($cart_id: String!, $code: String!, $pay_issuer: String) {
setPaymentMethodOnCart(input: {
cart_id: $cart_id
payment_method: {
code: $code,
pay_issuer: $pay_issuer
}
}) {
cart {
selected_payment_method {
code
}
}
}
}`,
{
cart_id: mask.value,
code: window.app.checkout.payment_method,
pay_issuer: window.app.checkout.pay_issuer
}
)
// Add pay_issuers to setPaymentMethodOnCart
query = config.queries.cart +
`

await window.magentoGraphQL(
`mutation payPlaceOrder($cart_id: String!, $pay_return_url: String, $pay_send_increment_id: Boolean) {
placeOrder(
input: {
cart_id: $cart_id,
pay_return_url: $pay_return_url,
pay_send_increment_id: $pay_send_increment_id
}
) {
order {
pay_redirect_url
}
}
}`,
{
'cart_id': mask.value,
'pay_return_url': window.url('/paynl/finish'),
'pay_send_increment_id': true
}
).then(response => {
if (response?.data?.placeOrder?.order?.pay_redirect_url) {
window.location.replace(response.data.placeOrder.order.pay_redirect_url)
mutation setPayPaymentMethodOnCart(
$cart_id: String!,
$code: String!,
$pay_issuer: String
) {
setPaymentMethodOnCart(input: {
cart_id: $cart_id,
payment_method: {
code: $code,
pay_issuer: $pay_issuer
}
})
}) {
cart { ...cart }
}
}`

variables.pay_issuer = window.app.custom.pay_issuer

return [query, variables, options];
});

addBeforePlaceOrderHandler(async function (query, variables, options) {
if (!cart.value?.selected_payment_method?.code?.includes('paynl_')) {
return [query, variables, options];
}

window.app.$on('before-checkout-payment-saved', (data) => {
if (!data.order.payment_method_code.includes('paynl_')) {
return;
// Add pay_return_url to placeorder
query = config.queries.order + config.queries.orderV2 +
`

mutation payPlaceOrder($cart_id: String!, $pay_return_url: String) {
placeOrder(
input: {
cart_id: $cart_id,
pay_return_url: $pay_return_url,
pay_send_increment_id: true
}
) {
order {
...order
}
orderV2 {
...orderV2
}
errors {
code
message
}
}
window.app.checkout.preventOrder = true
window.app.checkout.doNotGoToTheNextStep = true
}`

variables.pay_return_url = url('/checkout/success');

return [query, variables, options]
});

placeOrder(data);
});
})
addAfterPlaceOrderHandler(async function (response, mutationComponent) {
mutationComponent.redirect = response?.data?.placeOrder?.order?.pay_redirect_url || mutationComponent.redirect;
});
2 changes: 1 addition & 1 deletion resources/js/package.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import './eventlisteners'

document.addEventListener('vue:loaded', (event) => {
Vue.set(window.app.checkout, 'pay_issuer', null)
Vue.set(window.app.custom, 'pay_issuer', null)
});
1 change: 0 additions & 1 deletion resources/js/paynl.js

This file was deleted.

7 changes: 0 additions & 7 deletions resources/views/success.blade.php

This file was deleted.

8 changes: 0 additions & 8 deletions routes/web.php

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<?php

namespace Rapidez\Paynl\Http\Controllers;
namespace Rapidez\Paynl\Actions;

use Illuminate\Http\Client\RequestException;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use JustBetter\MagentoClient\Client\Magento;
use Rapidez\Core\Models\Scopes\IsActiveScope;

class FinishTransactionController extends Controller
class CheckSuccessfulOrder
{
/**
* @throws RequestException
Expand All @@ -18,7 +16,7 @@ public function __invoke(Request $request, Magento $magento)
$orderId = $request->get('orderId');
$incrementId = $request->get('incrementId');
if (empty($orderId)) {
return redirect(config('rapidez.paynl.fail_url'));
return true;
}

$magento
Expand All @@ -45,11 +43,21 @@ public function __invoke(Request $request, Magento $magento)

if (!data_get($response, 'data.paynlGetTransaction.isSuccess', false)) {
// https://github.com/paynl/magento2-graphql/blob/dcc3df5efceb43f6b8ec2c26833de7c52da0e564/Model/Resolver/RestoreCart.php#L66
config('rapidez.models.sales_order')::where('increment_id', $incrementId)->with(['quote' => fn($builder) => $builder->withoutGlobalScopes()])->first()->quote->update(['is_active' => 1]);

return redirect(config('rapidez.paynl.fail_url'));
config('rapidez.models.sales_order')::query()
->whereHas('sales_order_payments', fn($query) => $query
->where('additional_information->transactionId', $orderId)
)
->with([
'quote' => fn($query) => $query
->withoutGlobalScopes()
])
->first()
->quote
->update(['is_active' => 1]);

return false;
}

return view('paynl::success');
return true;
}
}
63 changes: 63 additions & 0 deletions src/Listeners/Healthcheck/PaynlHealthcheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Rapidez\Paynl\Listeners\Healthcheck;

use Rapidez\Core\Listeners\Healthcheck\Base;
use Rapidez\Core\Models\OauthToken;

class PaynlHealthcheck extends Base
{
public function handle()
{
$response = [
'healthy' => true,
'messages' => [],
];

if (!config('magento.connections.default.base_url')) {
$response['healthy'] = false;
$response['messages'][] = [
'type' => 'error',
'value' => __('Your Laravel Magento client base url is missing! don\'t forget to set "MAGENTO_BASE_URL". See: :link', ['link' => 'https://github.com/justbetter/laravel-magento-client#configuration']),
];
}

if (config('magento.connections.default.authentication_method') === 'token') {
$response = $this->performTokenMethodHealthChecks($response);
}

return $response;
}

protected function performTokenMethodHealthChecks(array $response) : array
{
if(!config('magento.connections.default.access_token')) {
$response['healthy'] = false;
$response['messages'][] = [
'type' => 'error',
'value' => __('Your Laravel Magento client access token is missing! don\'t forget to set "MAGENTO_ACCESS_TOKEN". See: :link', ['link' => 'https://github.com/justbetter/laravel-magento-client#authentication']),
];
}

/** @var OauthToken $oauthModel */
$oauthModel = config('rapidez.models.oauth_token');
if (!$oauthModel::query()->where('token', config('magento.connections.default.access_token'))->exists()) {
$response['healthy'] = false;
$response['messages'][] = [
'type' => 'error',
'value' => __('Your Laravel Magento client access token was not found in the database! Are you sure the integration is created and granted? See: :link', ['link' => 'https://github.com/justbetter/laravel-magento-client#authentication']),
];
}

$configModel = config('rapidez.models.config');
if (!$configModel::getCachedByPath('oauth/consumer/enable_integration_as_bearer', 0)) {
$response['healthy'] = false;
$response['messages'][] = [
'type' => 'error',
'value' => __('Your Laravel Magento client authentication method is "token", but your Magento settings prevent this! See: :link', ['link' => 'https://github.com/justbetter/laravel-magento-client#authentication']),
];
}

return $response;
}
}
26 changes: 18 additions & 8 deletions src/PaynlServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

namespace Rapidez\Paynl;

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
use Rapidez\Paynl\Actions\CheckSuccessfulOrder;
use Rapidez\Paynl\Listeners\Healthcheck\PaynlHealthcheck;
use TorMorten\Eventy\Facades\Eventy;

class PaynlServiceProvider extends ServiceProvider
{
Expand All @@ -13,12 +18,8 @@ class PaynlServiceProvider extends ServiceProvider
*/
public function boot()
{
$this->loadRoutesFrom(__DIR__.'/../routes/web.php');

$this->loadViewsFrom(__DIR__.'/../resources/views', 'paynl');

$this->mergeConfigFrom(__DIR__.'/../config/rapidez/paynl.php', 'rapidez.paynl');

if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__.'/../resources/views' => resource_path('views/vendor/paynl'),
Expand All @@ -27,10 +28,19 @@ public function boot()
$this->publishes([
__DIR__.'/../resources/payment-icons' => public_path('payment-icons'),
], 'payment-icons');

$this->publishes([
__DIR__.'/../config/rapidez/paynl.php' => config_path('rapidez/paynl.php'),
], 'config');
}

Route::get('paynl/checkout/finish', fn() => redirect(route('checkout.success', request()->query()), 308));

Eventy::addFilter('checkout.queries.order.data', function($attributes = []) {
$attributes[] = 'pay_redirect_url';
return $attributes;
});

Eventy::addFilter('checkout.checksuccess', function($success = true) {
return $success && App::call(CheckSuccessfulOrder::class);
});

PaynlHealthcheck::register();
}
}