#AlienSoft

1 messages ยท Page 1 of 1 (latest)

misty badgeBOT
sullen yoke
#

Hi ๐Ÿ‘‹

Payment Intents are not related to products. But I think you would want to start by looking into payment links.

bitter canopy
#

I'm basically having trouble displaying multiple payment methods i/e GBP and EUR

sullen yoke
#

Where?

bitter canopy
#

previously, I tried updating the payment intent with a new Price and currency which seems to be working, but that wasn't updating the UI where GBP works with cards/alipay/wechat and EUR works with iDEAL etc...

sullen yoke
#

Those are currencies, not payment methods

#

payment intents are not related to prices

#

So I think you are confused about the objects you are working with here

#

Price records are specific to currency as well

bitter canopy
#

ok, here's a simple scenario

#

i had a product with a GBP price and EUR price.

#

how do i go about showing that on my page

sullen yoke
#

On what page?

#

What surface are you using to accept payments?

bitter canopy
#

php/javascript

sullen yoke
#

Not what I asked

#

Are you using checkout?

#

payment element?

bitter canopy
#

payment element

sullen yoke
#

Okay so you set the currency on the Payment Intent. Each intent will be specific to one currency

#

Are you using Invoices?

bitter canopy
#

yes. i'm able to update the intent with the correct currency.
but the UI of the elements do not get updated.

sullen yoke
#

Because payment intents in themselves have no relationship to prices

bitter canopy
#

how do i force the UI's to be re-populated?

sullen yoke
#

Ah okya

misty badgeBOT
sullen yoke
#

This will update the Payment Element with changes from the Payment Intent

bitter canopy
#

would that just trigger/raise an event that there has been an update on the INTENT or would it cause to re-fresh/reload the payment-elemnt DIV ?

neat sparrow
#

๐Ÿ‘‹ stepping in

#

When you say you "update the intent" do you mean you create a different Invoice? Can you provide a specific example I can look at so that we are on the same page?

bitter canopy
#

I'm updating the intent on the server side with PHP

#

i'm not creating Invoices

neat sparrow
#

Okay thanks so then you aren't using Products/Prices which you mentioned above and is a bit confusing.

#

So yeah, if you fetchUpdates you should see Payment Element update to use the newly available Payment Method types based on currency

#

Have you tried doing this yet?

bitter canopy
#

ohh

#

i think im going in circles in terms of what I'm trying to achieve all week

#

everyone is telling me something differen.t

#

how do i sell a product with GBP and EUR ? it's that simple

neat sparrow
#

Well let's back up then and make sure we have all the details of what you are trying to do.

#

You decide on what currency you are going to use when you create the PaymentIntent and render Payment Element. So you know ahead of time from your customer whether they want GBP or EUR, no?

bitter canopy
#

i don't know ahead of time. That's the problem. They can select on the page GBP or EUR.

#

if you clicked the EUROPE vs International, the price changes between GBP and EUR also this updated the paymentIntent

#

but the UI elements are not rerendered accordingly

#

since when u select EUROPE it needs to populate iDeal etc...

#

this currently isn't using a PRODUCT from the dashboard. It's populating everything internally.

#

I thought, If i had a product, with GBP and EUR prices, then it would automatically RENDER the UI elements somehow by attaching the productID

#

which wouldn't require any paymentIntent currency/price updates etc..

neat sparrow
#

Yep okay so when the customer clicks the "Europe" toggle you need to call your backend and update the PaymentIntent's currency

#

Then on the frontend you call fetchUpdates

#

Then you will see the UI update

bitter canopy
#

ok trying fetchupdates now.. brb

#

Cannot read properties of undefined (reading 'getElement') ๐Ÿค”

neat sparrow
#

Sounds like you don't have your elements object in-scope of that function

#

Where you are trying to call elements.fetchUpdates

bitter canopy
#

on the EUROPE toggle

neat sparrow
#

Can you show me your client-side code here?

#

The relevant parts that is

#

How/where are you initializing elements to begin with?

bitter canopy
#

the elements obj is initialized in my checkout.js

#

but i'm trying to run the fetchUpdate from my frontend

#

so either I need to make it in to a function in my checkout.js and then call that from front end?

#

or I can add an Eventlistener that would raise the function from the checkout.js?

neat sparrow
#

Sorry, I don't understand. You initialize elements in your frontend to render Payment Element. You don't initialize elements from your backend.

#

Can you share your client-side code?

bitter canopy
#

async function initialize() {

const options = {
      mode: 'payment',
      amount: 12500,
      currency: 'gbp',
      // Fully customizable with appearance API.
      appearance: {/*...*/},

};
//elements.update({locale: 'fr'});

// Set up Stripe.js and Elements to use in checkout form
const elements = stripe.elements(options);

//const linkAuthenticationElement = elements.create("linkAuthentication");
//linkAuthenticationElement.mount("#link-authentication-element");

const paymentElementOptions = {
layout: "tabs",
paymentMethodOrder: ['card', 'iDeal', 'Alipay', 'wechat_pay'],
fields: {
billingDetails: {
name: "auto",
email: "never",
address: {
country: 'never',
postalCode: 'never'
}
}
}
};

const paymentElement = elements.create("payment", paymentElementOptions);
paymentElement.mount("#payment-element");

}

neat sparrow
#

Okay okay okay

#

So you are using deferred intent

bitter canopy
#

that renders the initial element

neat sparrow
#

Not the standard Payment Element flow

#

So you haven't even created your PaymentIntent when you render Payment Element here

bitter canopy
#

yh i was told to use that If i wanted separate currencies.

neat sparrow
#

Yeah that works fine for sure

bitter canopy
#

no my payment intent is generate via PHP when the page loads

#

@generated

neat sparrow
#

Oh you are passing paymentElementOptions to your elements.create not the options object

#

That threw me off

#

Okay

bitter canopy
#

i think it would be easier if you can INSPECT page on the browser, which would show you the .js stuff

#

might help

#

here's my INTENT:
$intent = \Stripe\PaymentIntent::create([
"amount" => ($amount) * 100,
"currency" => "gbp",
//"payment_method_types" => ["card"],
"payment_method_types" => ["card", "wechat", "alipay"],
//"automatic_payment_methods" => [
// "enabled" => true,
// ],

                ]);
neat sparrow
#

So yeah basically in that initialize function you want an eventListener where you call your backend to update the currency and then after you return a successful response from your backend then you call fetchUpdates()

#

Then your elements object will be in-scope

#

Where did you put fetchUpdates currently?

bitter canopy
#

currently fetchUpdate is a javascript on the onClick of the EUROPE tab

#

which is missing the ELEMENT OBJ as it's not in scope

neat sparrow
#

Right so you either can make your elements object a global variable or you can move your eventListener into your initialize function

bitter canopy
#

ok let me try a few things

#

document.addEventListener("tab1", handleUpdateUI);
document.addEventListener("tab2", handleUpdateUI);

function handleUpdateUI() {
console.log("imhere");

    elements.fetchUpdates()
      .then(function(result) {
        // Handle result.error
      });

}

#

doesn't that seem right?

#

not raising that event at all.... does it have to be a POST or something?

neat sparrow
#

"tab1" and "tab2" is not a valid event listener. You need a type there like "click"

#

But you need to access the HTML element beforehand

#

You can see an example there like: ```// Function to change the content of t2
function modifyText() {
const t2 = document.getElementById("t2");
const isNodeThree = t2.firstChild.nodeValue === "three";
t2.firstChild.nodeValue = isNodeThree ? "two" : "three";
}

// Add event listener to table
const el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);```

bitter canopy
#

oh i see

#

ok

#

ok so.. now it works! the event is fired but i still get an error

#

Cannot read properties of undefined (reading 'fetchUpdates')

#

eventhough my elements is a global var

#

let elements;
let paymentElement;
on top of .js page

neat sparrow
#

Looking

#

Looks like you forgot to remove the const elements

#

Change that to just elements =

bitter canopy
#

In order to call fetchUpdates, you must pass a valid PaymentIntent or SetupIntent client secret when creating the Elements group.

neat sparrow
#

Also where are you actually calling your backend?

bitter canopy
#

isn't there a way to fetch via php on server side? or must it be a front end thing

#

i/e when I'm updating the current on the paymentIntent. to also call fetchUpdates through php

neat sparrow
#

lol okay now looking at your actual full JS code you are using deferred intent.

bitter canopy
#

not much of a JS person, so please bare with me ๐Ÿ™‚

neat sparrow
#

As you pass options to stripe.elements()

#

Okay sorry -- I should have caught that before.

#

So in this case you don't want to fetchUpdates since you aren't (or at least shouldn't) actually be creating a PaymentIntent on page load

#

So try just replacing fetchUpdates with elements.update({currency: newCurrency});

bitter canopy
#

๐Ÿ˜ฎ

#

IT WORKS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#

WOW can't believe it after all week of trial and error ๐Ÿ˜„

#

ok now let's see if the actual payment works ๐Ÿ™‚

neat sparrow
#

lol glad it is working

#

So when you call your backend now you need to indicate which currency should be used to create the PaymentIntent based on which tab was selected last

bitter canopy
#

ok perfect so now i can switch between GBP / EUR currencies! thank you

#

final problem. seems with the confirmPayment

#

(index):1 Uncaught (in promise) IntegrationError: A valid Element name must be provided. Valid Elements are:
card, cardNumber, cardExpiry, cardCvc, postalCode, paymentRequestButton, iban, idealBank, p24Bank, auBankAccount, fpxBank, affirmMessage, afterpayClearpayMessage, paymentMethodMessaging; you passed: payment-element.

neat sparrow
#

From a brief look at your code I don't see where you are actually calling your backend

#

And why are you doing var paymentElement = elements.getElement('payment-element'); paymentElement.update({business: {name: 'Stripe Shop'}});

bitter canopy
#

that was from the STRIPE template

#

now i was asking my self why is there a BUSINESS name update ๐Ÿ™‚

#

ok now i removed those and get

neat sparrow
#

Yep indeed you are missing elements.submit()

#

You want to model your "pay" code based on that

bitter canopy
#

ok i see in the dashboard

#

"message": "Payment details were collected through Stripe Elements using automatic payment methods and cannot be confirmed with a Payment Intent configured with payment_method_types."
"type": "invalid_request_error"

neat sparrow
#

Change your PaymentIntent creation code to use 'automatic_payment_methods' => ['enabled' => true],

bitter canopy
#

yep

#

let's see

neat sparrow
#

Instead of payment_method_types

bitter canopy
#

๐Ÿ˜ฎ

#

WORRRRRRRRRRKSSS ๐Ÿ˜„

neat sparrow
#

๐ŸŽ‰

bitter canopy
#

๐Ÿฅณ

#

you have no idea how happy i am right now ๐Ÿ˜„

#

after so many days of failure

neat sparrow
#

So glad you could get it working!

bitter canopy
#

one last question. When would i update the DESCRIPTION field on the payment intent?

neat sparrow
#

Totally up to you

#

Doesn't really do anything per-say. You can use it as you prefer

bitter canopy
#

i only need it for visual purposes. as on the dashboard all you see is PAYMENT intents!!

#

whereas if i had a description, i can populate with the user email for example

#

can i do it on the stripe.confirmpayment ? cos i was gettin errors few days ago there

neat sparrow
#

No you have to do this from your backend

#

So you might just want to set it when you create the PaymentIntent

#

Since you should know all the info at that point any way

bitter canopy
#

$intent_response = \Stripe\PaymentIntent::update(
$_GET['intentId'],
[
'description' => $_GET['email1'].' : '.$_GET['country'],
'receipt_email' => $_GET['email1'],
]
);

#

i do have this on my backend but for some reason not updating/showing on dashboard?

#

that's why i thought i can do during submission or something

neat sparrow
#

Well are you ever calling that part of your backend?

#

Mostly though just pass it on creation

#

No need to update

bitter canopy
#

i don't know the details on creation though

#

intent is created on page load then user enters their data

neat sparrow
#

No it isn't ๐Ÿ™‚

#

Or it shouldn't be at least with the deffered intent flow

#

That is the whole point of that flow

#

That is when you would actually create the PaymentIntent

bitter canopy
#

oh i see! this is what i've been looking for all the time to create the intent on POST rather than on page load

#

which would eliminate UNNECESSARY loggon on the dashboard

neat sparrow
#

yep

bitter canopy
#

damn! i do have to leave for today though.. and continue tomorrow to finalize that part

#

can I reach you tomorrow if i need help on that ?

neat sparrow
#

We are here 24/5!

#

So just pop into the main channel and someone will be around

bitter canopy
#

cos these threads close after some time and new people get allocated on each chat

neat sparrow
#

Yeah it will just depend on who is online at the time.

#

I may or may not be around

bitter canopy
#

i've had 5 guys over the last week and no one was able to help, but YOU

#

๐Ÿ˜„

#

i 'll need YOUR assistance plz

neat sparrow
#

Everyone does their best :). Pop in the main channel and someone will be able to help!

bitter canopy
#

oks

#

well, thank you very much for your help today.

#

hope i see you around

neat sparrow
#

Have a good rest of the day!