worldcubeassociation.org icon indicating copy to clipboard operation
worldcubeassociation.org copied to clipboard

Add a Manual External Payment Integration

Open FinnIckler opened this issue 9 months ago • 24 comments

Replacement for #9737

This is still WIP because I didn't add any DB changes yet. I would like to have some feedback on this before.

I could not use the already existing connect_payment_integration method because that requires a redirect, which doesn't work in react world. I also think it doesn't really make sense, because there are no accounts to save.

I added a new page to input the payment information text and needed payment reference instead.

FinnIckler avatar Apr 09 '25 15:04 FinnIckler

image image

There are still a ton of small changes to be made, like adding to the CSV export and changing the single registration edit page

FinnIckler avatar Apr 10 '25 15:04 FinnIckler

Payment step during the registration: image

Payment step after payment: image

FinnIckler avatar Apr 10 '25 16:04 FinnIckler

(for the record: I had a lengthy discussion with Finn during our regular call, there are gonna be major reworks on this PR)

gregorbg avatar Apr 14 '25 09:04 gregorbg

I am cautiously setting this back to ready for review as I got payment working. I haven't touched refunds yet. The only odd thing right now is setting payment_reference in payment_finish. We can't set it in payment_ticket or else we can't distinguish between created and succeeded. I am setting it in

def find_payment_from_request(params)
    # The client secret is just the id of the database model, but we override the payment_reference
    # from the new one, so we can update it in update_status. This is simulating getting an updated version
    # from a payment provider after paying
    record = ManualPaymentRecord.find(params[:client_secret])
    record.payment_reference = params[:payment_reference]
    record
  end

so

def retrieve_remote
    self
end

will contain those changes and

def update_status(updated_record)
  update(payment_reference: updated_record.payment_reference)
end

can make them permanent.

Not ideal, but not sure what to do otherwise as retrieve_remote doesn't contain any parameters

FinnIckler avatar Apr 14 '25 15:04 FinnIckler

This looks like a great feature, Thank you WST for building this. I have one question: Can a user attach images to the payment information box? If not, is it possible to have that feature? It will be helpful for the UPI payment type, which has high usage in India

pranav-027 avatar Apr 17 '25 13:04 pranav-027

Can a user attach images to the payment information box? If not, is it possible to have that feature?

Technically, yes. Practically, meh. It is always complicated and cumbersome to host our own image uploads, with filetypes and screen sizes and preview thumbnails and whatnot. The effort it takes to implement may outweigh the benefits.

It will be helpful for the UPI payment type, which has high usage in India

Can you please elaborate on this? What good will an image upload do, that a simple "copy/paste of your completed payment receipt number" cannot do?

gregorbg avatar Apr 17 '25 13:04 gregorbg

Can you please elaborate on this? What good will an image upload do, that a simple "copy/paste of your completed payment receipt number" cannot do?

In India, we have UPI payments via QR code, which involves a customer using a UPI-enabled app to scan a QR code displayed by a merchant, enter the payment amount, and authorize the transaction using their UPI PIN. It would be great if organizers could upload an image of their payment QR code in the information box from their side. Image upload doesn’t need to be enabled for users who will be making the payments.

pranav-027 avatar Apr 17 '25 13:04 pranav-027

Thanks for the clarification! In that case I may have misunderstood. An image upload for the individual competitors who pay is indeed too complicated to realistically implement.

But an image upload for organizers is relatively easy and may in fact already work now! Markdown editors usually support image upload, if not it's easy for us to switch them on.

gregorbg avatar Apr 17 '25 13:04 gregorbg

yes, this just supports image uploads as part of the markdown

FinnIckler avatar Apr 17 '25 13:04 FinnIckler

@thewca-bot deploy staging

dunkOnIT avatar Apr 20 '25 14:04 dunkOnIT

I think this warning: image needs to be made generic after this feature.

Also, is there any discussion with WCAT to mandate payment integration if a competition has registration fees?

pranav-027 avatar Apr 27 '25 08:04 pranav-027

The original PR had that, but it required a lot of manual work by WCAT. The goal here is that we can make organizer onboard gradually and then make it compulsory at a later date

FinnIckler avatar Apr 27 '25 08:04 FinnIckler

If we really wanted to make this mandatory, then we also need to consider the "pay in person at the day of the competition at the venue" option. I guess they can easily fit their description, including which payment methods will be accepted at the venue, into the text box of this PR, but they won't need to collect any payment reference beforehand.

So maybe a "I don't want to collect any payment reference" optional checkbox would be prudent?

gregorbg avatar Apr 27 '25 08:04 gregorbg

@thewca-bot deploy staging

dunkOnIT avatar Apr 29 '25 07:04 dunkOnIT

@thewca-bot deploy staging

dunkOnIT avatar Apr 30 '25 09:04 dunkOnIT

@thewca-bot deploy staging

dunkOnIT avatar Apr 30 '25 10:04 dunkOnIT

@thewca-bot depoly staging

dunkOnIT avatar May 01 '25 05:05 dunkOnIT

you had a typo there :P

FinnIckler avatar May 01 '25 08:05 FinnIckler

@thewca-bot deploy staging

dunkOnIT avatar May 01 '25 08:05 dunkOnIT

I just noticed that we need to implement showing the payment reference in the admin table again

FinnIckler avatar May 02 '25 20:05 FinnIckler

Had inconsistent behaviour when trying to use this via the UI (sometimes the payment amount was showing 2x the competition's fees, other times it was failing outright), so adding tests to assert the backend behaviour

dunkOnIT avatar May 04 '25 14:05 dunkOnIT

Two related notes on the implementation here:

  • Should we be storing amount_iso and currency_code on the payment record? I'm not a big fan of this given that we're only inferring the information from the competition's settings, and so are very likely to end up in the situation where we're making confident assertions about payments amounts that are incorrect (already, I can give the example of CubingZA, who charge different amounts through their external payment service based on the number of days the competitor is attending the competition
    • At the very least, I'd say we shouldn't show this info to the user if there's some technological reason why it has to be stored (eg, we expect all payment_records to have those fields). But if we aren't showing it to the user, I'd again make the case that we should try not to store it at all
  • EDIT: Yes we do I wasn't thinking in enough detail about how our payment flow works. ~Do we need to/should we be creating a PaymentIntent for manual payments? It seems like all we need to be doing is checking/asserting the presence of a PaymentRecord, so the PaymentIntent seems redundant. At the same time, I recognize that we don't want to deviate from the current workflow too much, so this might well be a very shortsighted thought.~

dunkOnIT avatar May 04 '25 17:05 dunkOnIT

image Added the Payment Reference back to the Administration Panel

FinnIckler avatar May 05 '25 09:05 FinnIckler

When can we expect this super cool thing on prod?

pranav-027 avatar Jun 04 '25 17:06 pranav-027

superseeded by Duncan's PR

FinnIckler avatar Sep 18 '25 08:09 FinnIckler