@@ -54,10 +54,22 @@ public function mollie_create_payment($invoice_url_key)
5454
5555 // Handle the payment creation
5656 if ($ mollie_response ['status ' ]) {
57- // Save the transaction reference in session for callback
58- $ this ->session ->set_userdata ('mollie_transaction_ref ' , $ mollie_response ['reference ' ]);
57+ $ transaction_ref = $ mollie_response ['reference ' ];
5958
60- // Redirect to Mollie payment page
59+ // Save the transaction reference in session for callback (backup)
60+ $ this ->session ->set_userdata ('mollie_transaction_ref_ ' . $ invoice_url_key , $ transaction_ref );
61+
62+ // Record successful payment creation
63+ $ this ->db ->insert ('ip_merchant_responses ' , [
64+ 'invoice_id ' => $ invoice ->invoice_id ,
65+ 'merchant_response_successful ' => true ,
66+ 'merchant_response_date ' => date ('Y-m-d ' ),
67+ 'merchant_response_driver ' => 'mollie ' ,
68+ 'merchant_response ' => 'Payment created, awaiting customer action ' ,
69+ 'merchant_response_reference ' => 'transaction_ref: ' . $ transaction_ref ,
70+ ]);
71+
72+ // Redirect to Mollie payment page with transaction ref in URL
6173 redirect ($ mollie_response ['redirect_url ' ]);
6274 } else {
6375 // Record the failed transaction
@@ -80,14 +92,28 @@ public function mollie_create_payment($invoice_url_key)
8092 * The callback endpoint called by Mollie after payment.
8193 *
8294 * @param string $invoice_url_key
95+ * @param string $transaction_ref (optional, from URL parameter)
8396 *
8497 * @return void
8598 */
86- public function callback ($ invoice_url_key )
99+ public function callback ($ invoice_url_key, $ transaction_ref = null )
87100 {
101+ $ user_message = '' ;
102+ $ alert_type = 'error ' ;
103+
88104 try {
89- // Get transaction reference from session
90- $ transaction_ref = $ this ->session ->userdata ('mollie_transaction_ref ' );
105+ // Retrieve the invoice first
106+ $ this ->load ->model ('invoices/mdl_invoices ' );
107+ $ invoice = $ this ->mdl_invoices ->where ('ip_invoices.invoice_url_key ' , $ invoice_url_key )->get ()->row ();
108+
109+ if ( ! $ invoice ) {
110+ throw new Exception ('Invoice not found ' );
111+ }
112+
113+ // Get transaction reference from URL parameter or session (fallback)
114+ if ( ! $ transaction_ref ) {
115+ $ transaction_ref = $ this ->session ->userdata ('mollie_transaction_ref_ ' . $ invoice_url_key );
116+ }
91117
92118 if ( ! $ transaction_ref ) {
93119 throw new Exception ('No transaction reference found ' );
@@ -97,26 +123,23 @@ public function callback($invoice_url_key)
97123 $ mollie_response = $ this ->lib_mollie ->getPayment ($ transaction_ref );
98124
99125 if ( ! $ mollie_response ['status ' ]) {
100- throw new Exception ('Failed to fetch payment details ' );
126+ throw new Exception ('Failed to fetch payment details: ' . ( $ mollie_response [ ' message ' ] ?? ' Unknown error ' ) );
101127 }
102128
103- $ payment = $ mollie_response ['response ' ];
129+ $ payment = $ mollie_response ['response ' ];
130+ $ payment_data = $ payment ->getData ();
131+ $ status = $ payment_data ['status ' ] ?? 'unknown ' ;
104132
105- // Retrieve the invoice
106- $ this ->load ->model ('invoices/mdl_invoices ' );
107- $ invoice = $ this ->mdl_invoices ->where ('ip_invoices.invoice_url_key ' , $ invoice_url_key )->get ()->row ();
108-
109- if (!$ invoice ) {
110- throw new Exception ('Invoice not found ' );
133+ // Verify the payment belongs to this invoice
134+ $ metadata = $ payment_data ['metadata ' ] ?? [];
135+ if (isset ($ metadata ['invoice_key ' ]) && $ metadata ['invoice_key ' ] !== $ invoice_url_key ) {
136+ throw new Exception ('Payment does not belong to this invoice ' );
111137 }
112138
113- // Check if payment was successful
114- $ paid = $ payment ->isSuccessful ();
115-
116- if ($ paid ) {
117- // Save the payment
139+ // Handle different payment states
140+ if ($ payment ->isSuccessful ()) {
141+ // Payment successful - record it
118142 $ this ->load ->model ('payments/mdl_payments ' );
119- $ payment_data = $ payment ->getData ();
120143 $ payment_amount = isset ($ payment_data ['amount ' ]['value ' ])
121144 ? (float ) $ payment_data ['amount ' ]['value ' ]
122145 : (float ) $ invoice ->invoice_balance ;
@@ -128,39 +151,53 @@ public function callback($invoice_url_key)
128151 'payment_method_id ' => get_setting ('gateway_mollie_payment_method ' ),
129152 'payment_note ' => trans ('online_payment_intent_id ' ) . ': ' . $ transaction_ref ,
130153 ]);
154+
155+ $ response_msg = 'Payment successful: ' . $ status ;
156+ $ user_message = sprintf (trans ('online_payment_successful ' ), '# ' . $ invoice ->invoice_number );
157+ $ alert_type = 'success ' ;
158+ $ success = true ;
159+ } elseif ($ payment ->isPending ()) {
160+ // Payment is pending (e.g., bank transfer)
161+ $ response_msg = 'Payment pending: ' . $ status ;
162+ $ user_message = trans ('online_payment_pending ' );
163+ $ alert_type = 'info ' ;
164+ $ success = false ;
165+ } elseif ($ payment ->isCancelled ()) {
166+ // Payment was cancelled by user
167+ $ response_msg = 'Payment cancelled: ' . $ status ;
168+ $ user_message = trans ('online_payment_cancelled ' );
169+ $ alert_type = 'info ' ;
170+ $ success = false ;
171+ } else {
172+ // Payment failed, expired, or other status
173+ $ response_msg = 'Payment ' . $ status ;
174+ $ user_message = trans ('online_payment_failed ' );
175+ $ alert_type = 'error ' ;
176+ $ success = false ;
131177 }
132178
133179 // Record merchant response
134- $ response_msg = $ paid ? 'Payment successful '
135- : 'Payment ' . ($ payment ->getData ()['status ' ] ?? 'failed ' );
136-
137180 $ this ->db ->insert ('ip_merchant_responses ' , [
138181 'invoice_id ' => $ invoice ->invoice_id ,
139- 'merchant_response_successful ' => (int ) $ paid ,
182+ 'merchant_response_successful ' => (int ) $ success ,
140183 'merchant_response_date ' => date ('Y-m-d ' ),
141184 'merchant_response_driver ' => 'mollie ' ,
142185 'merchant_response ' => $ response_msg ,
143186 'merchant_response_reference ' => 'transaction_ref: ' . $ transaction_ref ,
144187 ]);
145188
146- // Notify user
147- if ($ paid ) {
148- $ this ->session ->set_flashdata (
149- 'alert_success ' ,
150- sprintf (trans ('online_payment_successful ' ), '# ' . $ invoice ->invoice_number )
151- );
152- } else {
153- $ this ->session ->set_flashdata (
154- 'alert_info ' ,
155- trans ('online_payment_failed ' )
156- );
157- }
189+ // Set user notification
190+ $ this ->session ->set_flashdata ('alert_ ' . $ alert_type , $ user_message );
158191
159192 // Clean up session
160- $ this ->session ->unset_userdata ('mollie_transaction_ref ' );
193+ $ this ->session ->unset_userdata ('mollie_transaction_ref_ ' . $ invoice_url_key );
161194 } catch (Error |Exception |ErrorException $ e ) {
162- // Log the error
163- log_message ('error ' , 'Mollie callback exception: ' . $ e ->getMessage ());
195+ // Log the error with context
196+ $ error_context = 'Mollie callback exception for invoice ' . $ invoice_url_key ;
197+ if (isset ($ transaction_ref )) {
198+ $ error_context .= ', transaction: ' . $ transaction_ref ;
199+ }
200+ log_message ('error ' , $ error_context . ' - ' . $ e ->getMessage ());
164201
165202 // Record error in merchant responses
166203 if (isset ($ invoice )) {
@@ -169,12 +206,17 @@ public function callback($invoice_url_key)
169206 'merchant_response_successful ' => false ,
170207 'merchant_response_date ' => date ('Y-m-d ' ),
171208 'merchant_response_driver ' => 'mollie ' ,
172- 'merchant_response ' => 'Error : ' . $ e ->getMessage (),
173- 'merchant_response_reference ' => 'none ' ,
209+ 'merchant_response ' => 'Callback error : ' . $ e ->getMessage (),
210+ 'merchant_response_reference ' => isset ( $ transaction_ref ) ? $ transaction_ref : 'none ' ,
174211 ]);
175212 }
176213
177- $ this ->session ->set_flashdata ('alert_error ' , trans ('online_payment_error ' ));
214+ // Provide more specific error message
215+ $ error_message = trans ('online_payment_error ' );
216+ if (str_contains ($ e ->getMessage (), 'not found ' )) {
217+ $ error_message .= ' ' . trans ('invoice_not_found ' );
218+ }
219+ $ this ->session ->set_flashdata ('alert_error ' , $ error_message );
178220 } finally {
179221 // Redirect to invoice
180222 redirect ('guest/view/invoice/ ' . $ invoice_url_key );
0 commit comments