public function test_process_payment__offsite__declined_then_approved() { /** @type EE_Payment_Method $pm */ $pm = $this->new_model_obj_with_dependencies('Payment_Method', array('PMD_type' => 'Mock_Offsite')); $transaction = $this->_new_typical_transaction(); global $wp_actions; EE_Registry::instance()->load_helper('Array'); $successful_payment_actions = EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0); /** @type EE_Payment_Processor $payment_processor */ $payment_processor = EE_Registry::instance()->load_core('Payment_Processor'); $payment = $payment_processor->process_payment($pm, $transaction, NULL, NULL, 'success', 'CART', TRUE, TRUE); $this->assertInstanceOf('EE_Payment', $payment); //verify it's already been saved $this->assertNotEquals(0, $payment->ID()); //assert that the payment still has its default status $this->assertEquals(EEM_Payment::instance()->field_settings_for('STS_ID')->get_default_value(), $payment->status()); $this->assertEquals(EEM_Payment::instance()->field_settings_for('STS_ID')->get_default_value(), $this->_get_payment_status_in_db($payment)); //assert that the we haven't notified of successful payment JUST yet... $this->assertEquals($successful_payment_actions, EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0)); //PENDING IPN $payment = $payment_processor->process_ipn(array('status' => EEM_Payment::status_id_pending, 'gateway_txn_id' => $payment->txn_id_chq_nmbr()), $transaction, $pm); $this->assertEquals(EEM_Payment::status_id_pending, $payment->status()); $this->assertEquals(EEM_Payment::status_id_pending, $this->_get_payment_status_in_db($payment)); //and the payment-approved action should have NOT been triggered $this->assertEquals($successful_payment_actions, EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0)); //APPROVED IPN $payment = $payment_processor->process_ipn(array('status' => EEM_Payment::status_id_approved, 'gateway_txn_id' => $payment->txn_id_chq_nmbr()), $transaction, $pm); //payment should be what the gateway set it to be, which was approved $this->assertEquals(EEM_Payment::status_id_approved, $payment->status()); $this->assertEquals(EEM_Payment::status_id_approved, $this->_get_payment_status_in_db($payment)); //and the payment-approved action should have been triggered $this->assertEquals($successful_payment_actions + 1, EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0)); //DUPLICATE SUCCESS IPN //for this, we need to reset payment model so we fetch a NEW payment object, instead of reusing the old //and because the payment method caches a payment method type which caches a gateway which caches the payment model, //we also need to reset the payment method EEM_Payment::reset(); $pm = EEM_Payment_Method::reset()->get_one_by_ID($pm->ID()); $payment = $payment_processor->process_ipn(array('status' => EEM_Payment::status_id_approved, 'gateway_txn_id' => $payment->txn_id_chq_nmbr()), $transaction, $pm); //payment should be what the gateway set it to be, which was failed $this->assertEquals(EEM_Payment::status_id_approved, $payment->status()); //and the payment-approved action should have NOT been triggered this time because it's a duplicate $this->assertEquals($successful_payment_actions + 1, EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0)); }