Skip to content

Commit 50d9941

Browse files
committed
Aktualisiere Stripe-Integration: Implementiere Payment Element Flow, füge Unterstützung für verschiedene Zahlungsmethoden hinzu und verbessere die Fehlerbehandlung bei Zahlungen.
1 parent 0bc7af7 commit 50d9941

File tree

4 files changed

+141
-68
lines changed

4 files changed

+141
-68
lines changed

app/controller/class-ms-controller-gateway.php

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,11 +345,54 @@ public function purchase_button( $subscription, $invoice ) {
345345
$member = $subscription->get_member();
346346
$stripe_customer_id = $member->get_gateway_profile( 'stripe', 'customer_id' );
347347
$stripe_price_id = MS_Gateway_Stripeplan::get_the_id( $membership->id, 'plan' );
348-
$success_url = home_url('/erfolg');
349-
$cancel_url = home_url('/abbruch');
348+
$reg_complete_url = MS_Model_Pages::get_page_url( MS_Model_Pages::MS_PAGE_REG_COMPLETE );
349+
$success_url = add_query_arg( 'redirect_status', 'success', $reg_complete_url );
350+
$cancel_url = add_query_arg( 'redirect_status', 'cancel', $reg_complete_url );
351+
352+
// Für Subscription (Abo):
353+
$allowed_methods_subscription = [
354+
'card',
355+
'sepa_debit',
356+
'bancontact',
357+
'ideal',
358+
'sofort',
359+
'bacs_debit',
360+
'au_becs_debit',
361+
'us_bank_account',
362+
'acss_debit',
363+
'afterpay_clearpay',
364+
'affirm',
365+
'klarna',
366+
];
367+
368+
// Für Single-Payment:
369+
$allowed_methods_single = [
370+
'card',
371+
'sofort',
372+
'giropay',
373+
'eps',
374+
'bancontact',
375+
'ideal',
376+
'p24',
377+
'alipay',
378+
'wechat_pay',
379+
'blik',
380+
'boleto',
381+
'oxxo',
382+
'acss_debit',
383+
'affirm',
384+
'afterpay_clearpay',
385+
'klarna',
386+
'us_bank_account',
387+
'au_becs_debit',
388+
'sepa_debit',
389+
// 'paypal', // NICHT aufnehmen!
390+
];
391+
392+
//$allowed_methods = $allowed_methods_subscription;
350393

351394
$session = \Stripe\Checkout\Session::create([
352-
'payment_method_types' => ['card'],
395+
'payment_method_types' => $allowed_methods,
353396
'mode' => 'subscription',
354397
'customer' => $stripe_customer_id,
355398
'line_items' => [[

app/gateway/stripe/class-ms-gateway-stripe-api.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,9 @@ public function create_payment_intent( $customer, $payment_method_id, $amount, $
557557
'description' => $description,
558558
'automatic_payment_methods' => [
559559
'enabled' => true,
560-
'allow_redirects' => 'never',
560+
//'allow_redirects' => 'never',
561561
],
562+
'return_url' => MS_Model_Pages::get_page_url( MS_Model_Pages::MS_PAGE_REG_COMPLETE ),
562563
]);
563564
}
564565

@@ -578,4 +579,19 @@ public function create_subscription( $customer, $payment_method_id, $plan_id ) {
578579
'expand' => ['latest_invoice.payment_intent'],
579580
]);
580581
}
582+
583+
/**
584+
* Erstellt einen PaymentIntent für das Payment Element (Abo-Start, alle Zahlungsarten).
585+
*/
586+
public function create_subscription_payment_intent( $customer, $amount, $currency, $description = '' ) {
587+
\Stripe\Stripe::setApiKey( $this->_gateway->get_secret_key() );
588+
$intent = \Stripe\PaymentIntent::create([
589+
'amount' => round( $amount * 100 ),
590+
'currency' => strtolower( $currency ),
591+
'customer' => $customer->id,
592+
'automatic_payment_methods' => ['enabled' => true],
593+
'description' => $description,
594+
]);
595+
return $intent->client_secret;
596+
}
581597
}

app/gateway/stripe/view/class-ms-gateway-stripe-view-card.php

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,35 +35,25 @@ public function to_html() {
3535
<script>
3636
document.addEventListener('DOMContentLoaded', function() {
3737
var stripe = Stripe('<?php echo esc_js( $publishable_key ); ?>');
38-
var elements = stripe.elements();
39-
var card = elements.create('card');
40-
card.mount('#ms-stripe-card-element');
41-
42-
card.on('change', function(event) {
43-
var displayError = document.getElementById('ms-stripe-card-errors');
44-
if (event.error) {
45-
displayError.textContent = event.error.message;
46-
} else {
47-
displayError.textContent = '';
48-
}
38+
var elements = stripe.elements({
39+
clientSecret: '<?php echo esc_js( $this->data["client_secret"] ); ?>'
4940
});
5041

42+
var appearance = { theme: 'stripe' };
43+
var paymentElement = elements.create('payment', {appearance});
44+
paymentElement.mount('#ms-stripe-card-element');
45+
5146
var form = document.getElementById('ms-stripe-payment-form');
5247
form.addEventListener('submit', function(event) {
5348
event.preventDefault();
54-
stripe.createPaymentMethod({
55-
type: 'card',
56-
card: card,
49+
stripe.confirmPayment({
50+
elements,
51+
confirmParams: {
52+
return_url: '<?php echo esc_js( MS_Model_Pages::get_page_url( MS_Model_Pages::MS_PAGE_REG_COMPLETE ) ); ?>'
53+
}
5754
}).then(function(result) {
5855
if (result.error) {
5956
document.getElementById('ms-stripe-card-errors').textContent = result.error.message;
60-
} else {
61-
var hiddenInput = document.createElement('input');
62-
hiddenInput.setAttribute('type', 'hidden');
63-
hiddenInput.setAttribute('name', 'stripePaymentMethod');
64-
hiddenInput.setAttribute('value', result.paymentMethod.id);
65-
form.appendChild(hiddenInput);
66-
form.submit();
6757
}
6858
});
6959
});

premium/gateway/stripeplan/class-ms-gateway-stripeplan.php

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -388,21 +388,45 @@ public function handle_webhook() {
388388
);
389389

390390
$this->_api->set_gateway( $this );
391+
$secret_key = $this->get_secret_key();
392+
\Stripe\Stripe::setApiKey( $secret_key );
391393

392-
$secret_key = $this->get_secret_key();
393-
\Stripe\Stripe::setApiKey( $secret_key );
394-
395-
// Make sure everyone is using the same API version. we can update this if/when necessary.
396-
// If we don't set this, Stripe will use latest version, which may break our implementation.
397-
//\Stripe\Stripe::setApiVersion( '2018-02-28' );
398-
399-
// retrieve the request's body and parse it as JSON
400394
$body = @file_get_contents( 'php://input' );
401-
402395
$this->log( $body );
403-
// grab the event information
404396
$event_json = json_decode( $body );
405397

398+
// NEU: Payment Element Flow
399+
if (isset($event_json->type) && $event_json->type === 'payment_intent.succeeded') {
400+
$payment_intent_id = $event_json->data->object->id;
401+
$customer_id = $event_json->data->object->customer;
402+
403+
$intent = \Stripe\PaymentIntent::retrieve($payment_intent_id);
404+
$payment_method_id = $intent->payment_method;
405+
406+
$plan_id = isset($intent->metadata->plan_id) ? $intent->metadata->plan_id : null;
407+
if (!$plan_id) {
408+
$this->log('Plan-ID nicht gefunden!');
409+
http_response_code(200);
410+
exit;
411+
}
412+
413+
$existing_subs = \Stripe\Subscription::all([
414+
'customer' => $customer_id,
415+
'limit' => 1,
416+
]);
417+
if (count($existing_subs->data) === 0) {
418+
$subscription = \Stripe\Subscription::create([
419+
'customer' => $customer_id,
420+
'items' => [['plan' => $plan_id]],
421+
'default_payment_method' => $payment_method_id,
422+
'expand' => ['latest_invoice.payment_intent'],
423+
]);
424+
$this->log('Stripe-Abo angelegt: ' . $subscription->id);
425+
}
426+
http_response_code(200);
427+
exit;
428+
}
429+
406430
if( isset( $event_json->id ) ) {
407431
try {
408432
$event_id = $event_json->id;
@@ -412,46 +436,46 @@ public function handle_webhook() {
412436
if ( $event && $this->valid_event( $event->type ) ) {
413437
$stripe_invoice = $event->data->object;
414438
if ( $stripe_invoice && isset( $stripe_invoice->id ) ) {
415-
$stripe_invoice_amount = $stripe_invoice->total / 100.0;
416-
$stripe_invoice_subtotal = $stripe_invoice->subtotal / 100.0;
417-
$stripe_customer = \Stripe\Customer::retrieve( $stripe_invoice->customer );
418-
$current_date = MS_Helper_Period::current_date( null, true );
439+
$stripe_invoice_amount = $stripe_invoice->total / 100.0;
440+
$stripe_invoice_subtotal = $stripe_invoice->subtotal / 100.0;
441+
$stripe_customer = \Stripe\Customer::retrieve( $stripe_invoice->customer );
442+
$current_date = MS_Helper_Period::current_date( null, true );
419443
if ( $stripe_customer ) {
420-
$email = $stripe_customer->email;
444+
$email = $stripe_customer->email;
421445

422446
if ( !function_exists( 'get_user_by' ) ) {
423-
include_once( ABSPATH . 'wp-includes/pluggable.php' );
447+
include_once( ABSPATH . 'wp-includes/pluggable.php' );
424448
}
425449

426-
$user = get_user_by( 'email', $email );
427-
if ( $user && !is_wp_error( $user ) ) {
428-
$member = MS_Factory::load( 'MS_Model_Member', $user->ID );
429-
$success = false;
430-
if ( $member ) {
450+
$user = get_user_by( 'email', $email );
451+
if ( $user && !is_wp_error( $user ) ) {
452+
$member = MS_Factory::load( 'MS_Model_Member', $user->ID );
453+
$success = false;
454+
if ( $member ) {
431455

432-
foreach ( $member->subscriptions as $subscription ) {
433-
if ( $subscription ) {
434-
if ( $subscription->is_system() ) { continue; }
435-
$membership = $subscription->get_membership();
436-
$stripe_sub = $this->_api->get_subscription_data(
437-
$stripe_invoice->lines->data,
438-
$membership
439-
);
440-
if ( $stripe_sub ) {
441-
switch ( $event->type ){
442-
case 'invoice.created' :
443-
if ( $membership->has_trial() ) {
444-
//$subscription->check_membership_status();
445-
//if ( $subscription->trial_period_completed ) {
446-
if( $subscription->status == MS_Model_Relationship::STATUS_TRIAL_EXPIRED &&
447-
MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_TRIAL )){
456+
foreach ( $member->subscriptions as $subscription ) {
457+
if ( $subscription ) {
458+
if ( $subscription->is_system() ) { continue; }
459+
$membership = $subscription->get_membership();
460+
$stripe_sub = $this->_api->get_subscription_data(
461+
$stripe_invoice->lines->data,
462+
$membership
463+
);
464+
if ( $stripe_sub ) {
465+
switch ( $event->type ){
466+
case 'invoice.created' :
467+
if ( $membership->has_trial() ) {
468+
//$subscription->check_membership_status();
469+
//if ( $subscription->trial_period_completed ) {
470+
if( $subscription->status == MS_Model_Relationship::STATUS_TRIAL_EXPIRED &&
471+
MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_TRIAL )){
448472

449-
$subscription->status = MS_Model_Relationship::STATUS_PENDING;
450-
$subscription->save();
451-
}
452-
}
453-
break;
454-
case 'invoice.payment_succeeded' :
473+
$subscription->status = MS_Model_Relationship::STATUS_PENDING;
474+
$subscription->save();
475+
}
476+
}
477+
break;
478+
case 'invoice.payment_succeeded' :
455479
if ( $current_date != $subscription->start_date ) {
456480
$invoice = $subscription->get_current_invoice();
457481

0 commit comments

Comments
 (0)