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

Fix display of pay later instructions on thankyou and skipping when payment on confirmation page #32502

Merged
merged 4 commits into from
Mar 28, 2025

Conversation

mattwire
Copy link
Contributor

@mattwire mattwire commented Mar 25, 2025

Overview

When a payment processor and pay later are enabled pay later instructions are always displayed on the ThankYou page.

Before

is_pay_later always set on ThankYou page.

After

Set per actual pay later status.

Technical Details

Explained via comments on this PR

Comments

Copy link

civibot bot commented Mar 25, 2025

🤖 Thank you for contributing to CiviCRM! ❤️ We will need to test and review this PR. 👷

Introduction for new contributors...
  • If this is your first PR, an admin will greenlight automated testing with the command ok to test or add to whitelist.
  • A series of tests will automatically run. You can see the results at the bottom of this page (if there are any problems, it will include a link to see what went wrong).
  • A demo site will be built where anyone can try out a version of CiviCRM that includes your changes.
  • If this process needs to be repeated, an admin will issue the command test this please to rerun tests and build a new demo site.
  • Before this PR can be merged, it needs to be reviewed. Please keep in mind that reviewers are volunteers, and their response time can vary from a few hours to a few weeks depending on their availability and their knowledge of this particular part of CiviCRM.
  • A great way to speed up this process is to "trade reviews" with someone - find an open PR that you feel able to review, and leave a comment like "I'm reviewing this now, could you please review mine?" (include a link to yours). You don't have to wait for a response to get started (and you don't have to stop at one!) the more you review, the faster this process goes for everyone 😄
  • To ensure that you are credited properly in the final release notes, please add yourself to contributor-key.yml
  • For more information about contributing, see CONTRIBUTING.md.
Quick links for reviewers...

➡️ Online demo of this PR 🔗

@civibot civibot bot added the master label Mar 25, 2025
$this->assign('is_pay_later', $params['is_pay_later']);
$this->assign('pay_later_text', $params['is_pay_later'] ? $this->getPayLaterLabel() : FALSE);
$this->assign('pay_later_receipt', $params['is_pay_later'] ? $this->_values['event']['pay_later_receipt'] : NULL);
$isPayLater = ($this->_values['event']['is_pay_later'] ?? FALSE);
Copy link
Contributor Author

@mattwire mattwire Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$params actually comes from the first event participant, we should be looking at the actual event data.
Also, $params seems to get reset to values from Register form (ie. throwing away changes on the Confirm form) when loaded on the ThankYou page so is_pay_later value is unreliable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been using $this->getEventValue('is_pay_later') rather than _values - the former is a direct apiv4 lookup with some caching whereas the latter seems a bit magic to me

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(also getEventValue() is supported for extensions to use so good to model it)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's pretty horrible the way event/participant params are passed around those forms. The problem is that both participant params and event (_values) are modified during form submission. The database value of is_pay_later is 1 for the event because pay later is enabled. But by the time we get to this point is_pay_later has been set to FALSE because we've submitted the form with a paymentprocessor. If you use the event value from the DB/API4 then you get contributions etc. with is_pay_later set to true when they are not..
I'd love to find another way of getting the form submission is_pay_later value but I couldn't find anything that didn't involve a massive refactoring of the params being passed around.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh that's dark - but does that mean is_pay_later === !$this->getSubmittedValue('payment_processor_id') ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's an idea.. getSubmittedValue() wasn't working properly but I fixed that as part of this PR so may now be a better option!

// If we submitted with no payment processor then we must be pay later - set it here.
$params[$participantNum]['is_pay_later'] = 1;
$params[$participantNum]['is_pay_later'] = $this->_values['event']['is_pay_later'] = 1;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set the pay later status based on the payment processor used on the confirm form

@@ -42,7 +42,7 @@
'type' => 'Array',
'default' => [],
'add' => '5.58',
'title' => ts('EXPERIMENTAL: Show Event Payment on Confirm?'),
'title' => ts('Show Event Payment on Confirm?'),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think it's time to remove the Experimental label...

Comment on lines +550 to +567
$this->assign('credit_card_type', $this->getSubmittedValue('credit_card_type'));
if ($this->getSubmittedValue('credit_card_exp_date')) {
$date = CRM_Utils_Date::format($this->getSubmittedValue('credit_card_exp_date'));
$date = CRM_Utils_Date::mysqlToIso($date);
}
$this->assign('credit_card_exp_date', $date ?? NULL);
$this->assign('credit_card_number',
CRM_Utils_System::mungeCreditCard($this->getSubmittedValue('credit_card_number') ?? '')
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should always be getting these fields from the original submitted values and not via a passed around $params array (which is actually first participant params with some extra sprinkled in)

$value = $this->controller->exportValue('Register', $fieldName);
}
if (!isset($value)) {
$value = parent::getSubmittedValue($fieldName);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fallback to generic function if we didn't find what we needed.

// were on the Register Page so we return them
$value = $this->controller->exportValue('Register', $fieldName);
if ($this->isShowPaymentOnConfirm() && in_array($this->getName(), ['Confirm', 'ThankYou'], TRUE)) {
$value = $this->controller->exportValue('Confirm', $fieldName);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll find payment fields on Confirm if payment was made on Confirm. Otherwise they'll be on Register

@@ -252,6 +252,7 @@ public function buildQuickForm() {
$this->assign('pay_later_receipt', '');
// @fixme These functions all seem to do similar things but take one away and the house of cards falls down..
$this->assignPaymentProcessor($this->_values['event']['is_pay_later']);
$this->preProcessPaymentOptions();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required only after the form is submitted to repopulate form fields so that eg. credit card fields can be retrieved via getSubmittedValue() from the ThankYou page. Otherwise they are lost.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattwire maybe we need an incode comment to that effect?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eileenmcnaughton good idea. Added

Comment on lines +163 to +165
<div class="content credit_card_type">{$credit_card_type}</div>
<div class="content credit_card_number">{$credit_card_number}</div>
<div class="content credit_card_exp_date">{if $credit_card_exp_date}{ts}Expires{/ts}: {$credit_card_exp_date|truncate:7:''|crmDate}{/if}</div>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Purely cosmetic but seems nice to be able to target each field separately.

@mattwire mattwire marked this pull request as ready for review March 25, 2025 19:16
@eileenmcnaughton eileenmcnaughton added the merge ready PR will be merged after a few days if there are no objections label Mar 26, 2025
@eileenmcnaughton
Copy link
Contributor

Just one thing outstanding - possible improvement of the code comments per comment above

@marcusjwilson
Copy link

Tested this patch on localdev and on a staging site, and it seems to work as expected and resolve the issue. Thank You, Both!

@eileenmcnaughton eileenmcnaughton merged commit 85ca7d0 into civicrm:master Mar 28, 2025
1 check passed
@eileenmcnaughton
Copy link
Contributor

thanks for testing @marcusjwilson

@mattwire mattwire deleted the eventpaylater branch March 28, 2025 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
master merge ready PR will be merged after a few days if there are no objections
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants