Abo: Doppelbestellung verhindern, Payment-Link loeschen & Pending-Status
Verhindert das Anlegen eines zweiten Abos (eigenes oder Kundenabo) wenn bereits eines initiiert ist bzw. ein offener Abo-Payment-Link existiert (redirectIfAboAlreadyInitiated). Payment-Links koennen jetzt geloescht werden, abgesichert ueber canDeleteInstance + Shop-Zugehoerigkeit, mit Erfolgs-/Fehler-Flash. Kundenabo-Uebersicht zeigt den Pending-Initial- Payment-Status (wartend / in Bearbeitung / fehlgeschlagen). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
42ef4dd1c6
commit
2b2847add1
7 changed files with 386 additions and 23 deletions
|
|
@ -151,12 +151,17 @@ class OrderController extends Controller
|
|||
}
|
||||
|
||||
if (Request::get('action') === 'next') {
|
||||
$selectedFor = Request::get('switchers-radio-is-for');
|
||||
if ($this->redirectIfAboAlreadyInitiated($selectedFor, $user, $delivery_id)) {
|
||||
return redirect(route('user_order_my_delivery', [$for, $delivery_id]));
|
||||
}
|
||||
|
||||
Yard::instance('shopping')->destroy();
|
||||
if (strpos(Request::get('switchers-radio-is-for'), 'ot') !== false) {
|
||||
if (strpos($selectedFor, 'ot') !== false) {
|
||||
$delivery_id = $id;
|
||||
}
|
||||
|
||||
return redirect(route('user_order_my_list', [Request::get('switchers-radio-is-for'), $delivery_id]));
|
||||
return redirect(route('user_order_my_list', [$selectedFor, $delivery_id]));
|
||||
}
|
||||
|
||||
return view('user.order.delivery', [
|
||||
|
|
@ -172,9 +177,8 @@ class OrderController extends Controller
|
|||
{
|
||||
$user = User::find(Auth::user()->id);
|
||||
|
||||
if ($for === 'abo-me' && AboHelper::userHasAbo($user)) {
|
||||
Log::channel(self::LOG_CHANNEL)->error("User #{$user->id} attempted to create abo but already has one");
|
||||
abort(403, 'User has an Abo. Cannot order.');
|
||||
if ($this->redirectIfAboAlreadyInitiated($for, $user, $id)) {
|
||||
return redirect(route('user_order_my_delivery', [$for, $id]));
|
||||
}
|
||||
|
||||
$shopping_user = null;
|
||||
|
|
@ -227,6 +231,10 @@ class OrderController extends Controller
|
|||
$data = Request::all();
|
||||
$user = User::find(Auth::user()->id);
|
||||
|
||||
if ($this->redirectIfAboAlreadyInitiated($for, $user, $id)) {
|
||||
return redirect(route('user_order_my_delivery', [$for, $id]));
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'shipping_salutation' => 'required',
|
||||
'shipping_firstname' => 'required',
|
||||
|
|
@ -336,6 +344,48 @@ class OrderController extends Controller
|
|||
return redirect(route('user_order_my_custom_payment', ['identifier' => $identifier]));
|
||||
}
|
||||
|
||||
private function redirectIfAboAlreadyInitiated(?string $for, User $user, $deliveryId = null): bool
|
||||
{
|
||||
if ($for === 'abo-me' && AboHelper::userHasAbo($user)) {
|
||||
Log::channel(self::LOG_CHANNEL)->warning("User #{$user->id} attempted to create abo but already has one initiated");
|
||||
\Session()->flash('custom-error', __('abo.error_user_has_initiated_abo'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($for === 'abo-ot-customer' && $deliveryId) {
|
||||
$shoppingUser = Shop::checkShoppingUser($deliveryId, $user);
|
||||
if (AboHelper::hasAboByEmail($shoppingUser->billing_email) || $this->hasOpenAboPaymentLink($user, $shoppingUser->billing_email)) {
|
||||
Log::channel(self::LOG_CHANNEL)->warning("User #{$user->id} attempted to create customer abo but one is already initiated", [
|
||||
'shopping_user_id' => $shoppingUser->id,
|
||||
'email' => $shoppingUser->billing_email,
|
||||
]);
|
||||
\Session()->flash('custom-error', __('abo.error_email_has_abo', ['email' => $shoppingUser->billing_email]));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function hasOpenAboPaymentLink(User $user, string $email): bool
|
||||
{
|
||||
$userShopId = $user->shop ? $user->shop->id : null;
|
||||
if (! $userShopId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ShoppingInstance::where('user_shop_id', $userShopId)
|
||||
->where('payment', 6)
|
||||
->where('status', '<', 10)
|
||||
->get()
|
||||
->contains(function (ShoppingInstance $shoppingInstance) use ($email) {
|
||||
return OrderPaymentService::isAboCustomerPaymentLink($shoppingInstance)
|
||||
&& strcasecmp((string) ($shoppingInstance->shopping_data['billing_email'] ?? ''), $email) === 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Process payment for user orders
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
|
||||
use Request;
|
||||
use App\User;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Services\OrderPaymentService;
|
||||
use App\User;
|
||||
|
||||
class OrderPaymentController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('active.account');
|
||||
|
|
@ -22,6 +18,7 @@ class OrderPaymentController extends Controller
|
|||
{
|
||||
$data = [
|
||||
];
|
||||
|
||||
return view('user.order.payment.index', $data);
|
||||
}
|
||||
|
||||
|
|
@ -29,15 +26,34 @@ class OrderPaymentController extends Controller
|
|||
{
|
||||
$data = OrderPaymentService::getCustomPayment($identifier);
|
||||
$data['backlink'] = route('user_order_payment_links');
|
||||
|
||||
return view('user.order.payment.custom_payment', $data);
|
||||
}
|
||||
|
||||
public function delete($identifier){
|
||||
public function delete($identifier)
|
||||
{
|
||||
$shoppingInstance = ShoppingInstance::where('identifier', $identifier)->firstOrFail();
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$userShopId = $user->shop ? $user->shop->id : null;
|
||||
|
||||
if ((int) $shoppingInstance->user_shop_id !== (int) $userShopId) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
if (! OrderPaymentService::canDeleteInstance($shoppingInstance)) {
|
||||
\Session()->flash('alert-error', __('abo.payment_link_delete_not_allowed'));
|
||||
|
||||
return redirect(route('user_order_payment_links'));
|
||||
}
|
||||
|
||||
OrderPaymentService::deleteInstance($identifier);
|
||||
\Session()->flash('alert-success', __('abo.payment_link_delete_success'));
|
||||
|
||||
return redirect(route('user_order_payment_links'));
|
||||
}
|
||||
|
||||
public function datatable(){
|
||||
public function datatable()
|
||||
{
|
||||
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$user_shop_id = $user->shop ? $user->shop->id : null;
|
||||
|
|
@ -50,7 +66,7 @@ class OrderPaymentController extends Controller
|
|||
return '<a href="'.route('user_order_payment_links_detail', [$shoppingInstance->identifier]).'" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('created_at', function (ShoppingInstance $shoppingInstance) {
|
||||
return $shoppingInstance->created_at->format("d.m.Y");
|
||||
return $shoppingInstance->created_at->format('d.m.Y');
|
||||
})
|
||||
->addColumn('status', function (ShoppingInstance $shoppingInstance) {
|
||||
return OrderPaymentService::getStatusBadge($shoppingInstance);
|
||||
|
|
@ -59,9 +75,9 @@ class OrderPaymentController extends Controller
|
|||
return $shoppingInstance->payment_method ? $shoppingInstance->payment_method->name : '-';
|
||||
})
|
||||
->addColumn('total', function (ShoppingInstance $shoppingInstance) {
|
||||
if($shoppingInstance->amount > 0){
|
||||
return '<span class="no-line-break">'.$shoppingInstance->getAmountFormatted()." €</span>";
|
||||
}else{
|
||||
if ($shoppingInstance->amount > 0) {
|
||||
return '<span class="no-line-break">'.$shoppingInstance->getAmountFormatted().' €</span>';
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
})
|
||||
|
|
@ -78,12 +94,16 @@ class OrderPaymentController extends Controller
|
|||
return $shoppingInstance->shopping_data['billing_email'] ?? '-';
|
||||
})
|
||||
->addColumn('delete', function (ShoppingInstance $shoppingInstance) {
|
||||
if (! OrderPaymentService::canDeleteInstance($shoppingInstance)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<a onclick="return confirm(\''.__('confirm_delete').'\');" href="'.route('user_order_payment_links_delete', [$shoppingInstance->identifier]).'" class="btn icon-btn btn-sm btn-danger"><span class="fa fa-trash"></span></a>';
|
||||
})
|
||||
|
||||
|
||||
->orderColumn('id', 'identifier $1')
|
||||
->orderColumn('created_at', 'created_at $1')
|
||||
->orderColumn('status', 'status $1')
|
||||
->orderColumn('status', 'status $1')
|
||||
->orderColumn('total', 'total $1')
|
||||
->orderColumn('type', 'type $1')
|
||||
->orderColumn('billing_firstname', 'billing_firstname $1')
|
||||
|
|
@ -92,6 +112,4 @@ class OrderPaymentController extends Controller
|
|||
->rawColumns(['id', 'status', 'type', 'total', 'invoice', 'delete'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ namespace App\Services;
|
|||
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserAbo;
|
||||
use App\User;
|
||||
use Yard;
|
||||
|
||||
class OrderPaymentService
|
||||
|
|
@ -21,6 +23,52 @@ class OrderPaymentService
|
|||
}*/
|
||||
}
|
||||
|
||||
public static function isAboCustomerPaymentLink(ShoppingInstance $shoppingInstance): bool
|
||||
{
|
||||
return (int) $shoppingInstance->payment === 6
|
||||
&& ($shoppingInstance->shopping_data['is_for'] ?? null) === 'abo-ot-customer'
|
||||
&& (bool) ($shoppingInstance->shopping_data['is_abo'] ?? false);
|
||||
}
|
||||
|
||||
public static function canDeleteInstance(ShoppingInstance $shoppingInstance): bool
|
||||
{
|
||||
return in_array((int) $shoppingInstance->status, [0, 1, 5, 6], true);
|
||||
}
|
||||
|
||||
public static function isPaymentProcessing(ShoppingInstance $shoppingInstance): bool
|
||||
{
|
||||
return in_array((int) $shoppingInstance->status, [2, 3, 4], true);
|
||||
}
|
||||
|
||||
public static function isPaymentFailed(ShoppingInstance $shoppingInstance): bool
|
||||
{
|
||||
return in_array((int) $shoppingInstance->status, [5, 6], true);
|
||||
}
|
||||
|
||||
public static function hasUserAboForPaymentLink(ShoppingInstance $shoppingInstance, User $user): bool
|
||||
{
|
||||
$shoppingUserId = (int) ($shoppingInstance->shopping_user_id ?: ($shoppingInstance->shopping_data['shopping_user_id'] ?? 0));
|
||||
$email = trim((string) ($shoppingInstance->shopping_data['billing_email'] ?? ''));
|
||||
|
||||
if ($shoppingUserId <= 0 && $email === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return UserAbo::where('member_id', $user->id)
|
||||
->where('is_for', 'ot')
|
||||
->where('status', '>=', 1)
|
||||
->where(function ($query) use ($shoppingUserId, $email) {
|
||||
if ($shoppingUserId > 0) {
|
||||
$query->orWhere('shopping_user_id', $shoppingUserId);
|
||||
}
|
||||
|
||||
if ($email !== '') {
|
||||
$query->orWhereRaw('LOWER(email) = ?', [mb_strtolower($email)]);
|
||||
}
|
||||
})
|
||||
->exists();
|
||||
}
|
||||
|
||||
public static function updateInstanceStatus($identifier, $status, $lower = true)
|
||||
{
|
||||
if (! ShoppingInstance::where('identifier', $identifier)->exists()) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,17 @@
|
|||
{{ __('navigation.payment_links') }} / {{ __('navigation.overview') }}
|
||||
</h4>
|
||||
|
||||
@if (Session::has('alert-success'))
|
||||
<div class="alert alert-success">
|
||||
{{ Session::get('alert-success') }}
|
||||
</div>
|
||||
@endif
|
||||
@if (Session::has('alert-error'))
|
||||
<div class="alert alert-danger">
|
||||
{{ Session::get('alert-error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Status-Legende --}}
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
|
|
@ -68,4 +79,4 @@
|
|||
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -106,6 +106,17 @@
|
|||
<span class="badge badge-outline-secondary">
|
||||
{{ __('tables.customer') }} #{{ $index + 1 }}
|
||||
</span>
|
||||
@if($abo->isPendingInitialPayment())
|
||||
<div class="small text-warning mt-1">
|
||||
@if($abo->hasFailedInitialPayment())
|
||||
{{ __('abo.pending_payment_failed_title') }}
|
||||
@elseif($abo->hasInitialPaymentStatus())
|
||||
{{ __('abo.pending_payment_processing_title') }}
|
||||
@else
|
||||
{{ __('abo.pending_payment_waiting_title') }}
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<strong class="text-primary">
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ Route::domain(config('app.pre_url_crm').config('app.domain').config('app.tld_car
|
|||
Route::post('/user/abos/update/{view}/{id}', 'User\AboController@update')->name('user_abos_update');
|
||||
Route::post('/user/abos/onetime/{view}/{id}', 'User\AboController@oneTime')->name('user_abos_onetime');
|
||||
Route::post('/user/abos/retry-payment/{view}/{id}', 'User\AboController@retryPayment')->name('user_abos_retry_payment');
|
||||
Route::post('/user/abos/delete-pending/{view}/{id}', 'User\AboController@deletePending')->name('user_abos_delete_pending');
|
||||
Route::post('/user/abos/payment-link/delete/{identifier}', 'User\AboController@deletePaymentLink')->name('user_abos_payment_link_delete');
|
||||
Route::get('/user/abo/datatable/{id}', 'User\AboController@datatable')->name('user_abo_datatable');
|
||||
Route::get('/user/abo/onetime-datatable/{id}', 'User\AboController@oneTimeDatatable')->name('user_abo_onetime_datatable');
|
||||
// Route to show team subscriptions (Abos)
|
||||
|
|
|
|||
223
tests/Feature/AboPendingInitialPaymentTest.php
Normal file
223
tests/Feature/AboPendingInitialPaymentTest.php
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Country;
|
||||
use App\Models\Shipping;
|
||||
use App\Models\ShippingCountry;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserAbo;
|
||||
use App\Models\UserAboOrder;
|
||||
use App\Models\UserShop;
|
||||
use App\Services\AboHelper;
|
||||
use App\Services\OrderPaymentService;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Tests\TestCase;
|
||||
|
||||
uses(TestCase::class, RefreshDatabase::class);
|
||||
|
||||
it('behandelt neue noch nicht bestaetigte Eigen-Abos als vorhandenes Abo', function (): void {
|
||||
$fixture = createPendingInitialAboFixture();
|
||||
|
||||
expect(AboHelper::userHasAbo($fixture['user']))->toBeTrue()
|
||||
->and($fixture['userAbo']->isPendingInitialPayment())->toBeTrue()
|
||||
->and($fixture['userAbo']->hasInitialPaymentStatus())->toBeFalse()
|
||||
->and($fixture['userAbo']->canDeletePendingInitialPayment())->toBeFalse();
|
||||
});
|
||||
|
||||
it('behandelt neue Kunden-Abos anhand der E-Mail als vorhandenes Abo', function (): void {
|
||||
$fixture = createPendingInitialAboFixture(['is_for' => 'ot']);
|
||||
|
||||
expect(AboHelper::hasAboByEmail($fixture['shoppingUser']->billing_email))->toBeTrue()
|
||||
->and(AboHelper::memberHasAbo($fixture['shoppingUser']))->toBeTrue();
|
||||
});
|
||||
|
||||
it('erlaubt das Loeschen eines neuen Abo-Eintrags erst bei fehlgeschlagener Erstzahlung', function (): void {
|
||||
$fixture = createPendingInitialAboFixture(paymentOverrides: ['txaction' => 'failed']);
|
||||
|
||||
expect($fixture['userAbo']->fresh()->hasInitialPaymentStatus())->toBeTrue()
|
||||
->and($fixture['userAbo']->fresh()->hasFailedInitialPayment())->toBeTrue()
|
||||
->and($fixture['userAbo']->fresh()->canDeletePendingInitialPayment())->toBeTrue();
|
||||
});
|
||||
|
||||
it('erlaubt Abo-Zahlungslink-Loeschung nur vor Zahlung oder nach Fehler', function (): void {
|
||||
foreach ([0, 1, 5, 6] as $status) {
|
||||
$instance = new ShoppingInstance(['status' => $status]);
|
||||
expect(OrderPaymentService::canDeleteInstance($instance))->toBeTrue();
|
||||
}
|
||||
|
||||
foreach ([2, 3, 4, 10] as $status) {
|
||||
$instance = new ShoppingInstance(['status' => $status]);
|
||||
expect(OrderPaymentService::canDeleteInstance($instance))->toBeFalse();
|
||||
}
|
||||
});
|
||||
|
||||
it('zeigt gesendete Abo-Zahlungslinks in der Kunden-Abo-Uebersicht', function (): void {
|
||||
URL::resolveMissingNamedRoutesUsing(fn (string $name, array $parameters) => '/'.$name.'/'.implode('/', $parameters));
|
||||
|
||||
$fixture = createPendingInitialAboFixture();
|
||||
$this->actingAs($fixture['user']);
|
||||
$paymentLink = new ShoppingInstance([
|
||||
'identifier' => 'paylink-'.uniqid(),
|
||||
'user_shop_id' => $fixture['userShop']->id,
|
||||
'payment' => 6,
|
||||
'subdomain' => 'test.local',
|
||||
'country_id' => $fixture['countryId'],
|
||||
'amount' => 99.50,
|
||||
'shopping_user_id' => $fixture['shoppingUser']->id,
|
||||
'status' => 0,
|
||||
'shopping_data' => [
|
||||
'is_for' => 'abo-ot-customer',
|
||||
'is_abo' => true,
|
||||
'billing_email' => $fixture['shoppingUser']->billing_email,
|
||||
],
|
||||
]);
|
||||
$paymentLink->created_at = now();
|
||||
|
||||
$html = view('user.abo.index', [
|
||||
'user_abos' => collect(),
|
||||
'abo_payment_links' => collect([$paymentLink]),
|
||||
'view' => 'ot',
|
||||
'isAdmin' => false,
|
||||
])->render();
|
||||
|
||||
expect($html)
|
||||
->toContain(__('abo.payment_link_sent_title'))
|
||||
->toContain($paymentLink->identifier)
|
||||
->toContain($fixture['shoppingUser']->billing_email)
|
||||
->toContain(__('delete'));
|
||||
});
|
||||
|
||||
it('blendet Abo-Zahlungslinks aus sobald daraus ein Abo existiert', function (): void {
|
||||
$fixture = createPendingInitialAboFixture(['is_for' => 'ot']);
|
||||
$paymentLink = new ShoppingInstance([
|
||||
'user_shop_id' => $fixture['userShop']->id,
|
||||
'payment' => 6,
|
||||
'shopping_user_id' => $fixture['shoppingUser']->id,
|
||||
'status' => 3,
|
||||
'shopping_data' => [
|
||||
'is_for' => 'abo-ot-customer',
|
||||
'is_abo' => true,
|
||||
'shopping_user_id' => $fixture['shoppingUser']->id,
|
||||
'billing_email' => $fixture['shoppingUser']->billing_email,
|
||||
],
|
||||
]);
|
||||
|
||||
expect(OrderPaymentService::hasUserAboForPaymentLink($paymentLink, $fixture['user']))->toBeTrue();
|
||||
});
|
||||
|
||||
/**
|
||||
* @return array{user: User, userShop: UserShop, shoppingUser: ShoppingUser, userAbo: UserAbo, payment: ShoppingPayment, countryId: int}
|
||||
*/
|
||||
function createPendingInitialAboFixture(array $aboOverrides = [], array $paymentOverrides = []): array
|
||||
{
|
||||
$country = Country::create([
|
||||
'code' => 'DE',
|
||||
'phone' => '49',
|
||||
'en' => 'Germany',
|
||||
'de' => 'Deutschland',
|
||||
'es' => 'Alemania',
|
||||
'fr' => 'Allemagne',
|
||||
'it' => 'Germania',
|
||||
'ru' => 'Deutschland',
|
||||
]);
|
||||
|
||||
$shipping = Shipping::create([
|
||||
'name' => 'Standard',
|
||||
'active' => true,
|
||||
]);
|
||||
|
||||
$shippingCountry = ShippingCountry::create([
|
||||
'shipping_id' => $shipping->id,
|
||||
'country_id' => $country->id,
|
||||
]);
|
||||
|
||||
$user = User::forceCreate([
|
||||
'email' => 'pending-abo-'.uniqid('', true).'@example.com',
|
||||
'password' => bcrypt('secret'),
|
||||
'lang' => 'de',
|
||||
]);
|
||||
|
||||
$userShop = UserShop::create([
|
||||
'user_id' => $user->id,
|
||||
'name' => 'TS'.substr(uniqid('', true), 0, 8),
|
||||
'slug' => 'ts-'.uniqid(),
|
||||
'active' => true,
|
||||
]);
|
||||
|
||||
$shoppingUser = ShoppingUser::create([
|
||||
'auth_user_id' => $user->id,
|
||||
'member_id' => $user->id,
|
||||
'billing_country_id' => $country->id,
|
||||
'shipping_country_id' => $country->id,
|
||||
'billing_email' => 'pending-customer-'.uniqid('', true).'@example.com',
|
||||
'shipping_email' => $user->email,
|
||||
'is_for' => $aboOverrides['is_for'] ?? 'me',
|
||||
'is_from' => 'user_order',
|
||||
]);
|
||||
|
||||
$shoppingOrder = ShoppingOrder::create([
|
||||
'shopping_user_id' => $shoppingUser->id,
|
||||
'auth_user_id' => $user->id,
|
||||
'member_id' => $user->id,
|
||||
'country_id' => $shippingCountry->id,
|
||||
'user_shop_id' => $userShop->id,
|
||||
'payment_for' => 2,
|
||||
'is_abo' => true,
|
||||
'abo_interval' => 5,
|
||||
'paid' => false,
|
||||
'mode' => 'test',
|
||||
'total' => 100,
|
||||
'subtotal' => 90,
|
||||
]);
|
||||
|
||||
$payment = ShoppingPayment::create(array_merge([
|
||||
'shopping_order_id' => $shoppingOrder->id,
|
||||
'reference' => 'pending-ref-'.uniqid(),
|
||||
'amount' => 10000,
|
||||
'currency' => 'EUR',
|
||||
'clearingtype' => 'cc',
|
||||
'abo_interval' => 5,
|
||||
'mode' => 'test',
|
||||
], $paymentOverrides));
|
||||
|
||||
if (array_key_exists('txaction', $paymentOverrides)) {
|
||||
$payment->txaction = $paymentOverrides['txaction'];
|
||||
$payment->save();
|
||||
}
|
||||
|
||||
$userAbo = UserAbo::create(array_merge([
|
||||
'user_id' => $user->id,
|
||||
'member_id' => $user->id,
|
||||
'shopping_user_id' => $shoppingUser->id,
|
||||
'email' => $shoppingUser->billing_email,
|
||||
'is_for' => $aboOverrides['is_for'] ?? 'me',
|
||||
'payone_userid' => 0,
|
||||
'clearingtype' => 'cc',
|
||||
'amount' => 10000,
|
||||
'status' => 1,
|
||||
'abo_interval' => 5,
|
||||
'start_date' => now(),
|
||||
'last_date' => now(),
|
||||
'next_date' => now()->addMonth(),
|
||||
], $aboOverrides));
|
||||
|
||||
UserAboOrder::create([
|
||||
'user_abo_id' => $userAbo->id,
|
||||
'shopping_order_id' => $shoppingOrder->id,
|
||||
'status' => 1,
|
||||
'paid' => false,
|
||||
]);
|
||||
|
||||
return [
|
||||
'user' => $user,
|
||||
'userShop' => $userShop,
|
||||
'shoppingUser' => $shoppingUser,
|
||||
'userAbo' => $userAbo,
|
||||
'payment' => $payment,
|
||||
'countryId' => $shippingCountry->id,
|
||||
];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue