Passing text element value as price to Wix Pay

I’m trying to pass a calculated value from a text element as the price to be paid in Wix Payments and I’m a bit stuck.
Based on 3 dropdown selections a user makes a total price is calculated through my displayPrice() function (by adding cells from a database collection) and is then displayed on page through a text element. I’m then trying to pass that value to the Wix Payments API as the price to be paid.
The problem is my payButton_click() is returning undefined and I’m not sure what is missing.

Here’s what I have so far.

/***********************

  • BACKEND CODE *
    ************************/

// import wixPay module
import wixPay from ‘wix-pay-backend’ ;

// function called by frontend-- takes price parameter
export function createPaymentForFlight ( price ){
// returns a sort of payment object
return wixPay . createPayment ({
items: [{
name: “Dynamically Priced Product” ,
price: price
}],
amount: price
})
}

/************************

  • FRONTEND CODE *
    *************************/

const db = “databaseCollection”

// function that calculates and display total price in text element based on user dropdown selections
function displayPrice () {
wixData . query ( db )
. hasAll ( “foo” , $w ( “#dropdown1” ). value )
. hasAll ( “bar” , $w ( “#dropdown2” ). value )
. hasAll ( “baz” , $w ( “#dropdown3” ). value )
. find ()
. then (( results ) => {
let currency = {
style: “currency” ,
currency: “USD”
}
let objectPrice = results . items [ 0 ]. price
let fee1 = results . items [ 0 ]. fee1
let fee2 = results . items [ 0 ]. fee2
let fee3 = results . items [ 0 ]. fee3
let taxes = 1.05
const totalPrice = ( objectPrice + fee1 + fee2 + fee3 )* taxes

	 // update the text element on page with the total price in currency format 
	$w ( "#textShowingPrice" ). text  =  totalPrice . toLocaleString ( "en-US" ,  currency ); 
}) 
. catch (( err )  =>  console . log ( err )); 

}

// button click that should start payment flow
export function payButton_click ( event ) {
let price = $w ( “textShowingPrice” ). text ;
console . log ( price );

// calling backend function and passing it our price data 
createPaymentForFlight ( price ). then ( payment  =>  { 
	// starts payment process, opening  
	wixPay . startPayment ( payment . id ); 
}); 

}

Problem is the type of element you are trying to pass “String” to a number. You need to convert it to a number first after that pass it to the parameter.

You don’t need to use parseInt you can use different methods but best option is this one. Also you can try to use Wix Billing Backend codes to run better custom payments.

Also do not forget to pass total amount in Wix Pay if you don’t it will not work. And as I see you did it already.

let price =  parseInt($w("#textShowingPrice").text)

Check docs every time (do not be like me xd)

That’s a big NO NO

Don’t ever pass PRICE from frontend to backend. That means someone could modify you frontend to send a price of $1 and your system would process it.

Rather than computing the price on the frontend, the backend should receive all the information to compute the price as a parameter .

import wixPay from 'wix-pay-backend';/
export async function createPaymentForFlight(foo, bar, baz ){
 price = await computePrice(foo, bar, baz);
 return wixPay.createPayment({
 items: [{name: "Dynamically Priced Product", price: price
 }],
 amount: price
 })}

export function compturePrice(foo, bar, baz) {
 return wixData.query(db).hasAll("foo", foo).hasAll("bar", bar).hasAll("baz", baz).find().then((results) => {let currency = {style: "currency",
 currency: "USD"
 }let objectPrice = results.items[0].pricelet fee1 = results.items[0].fee1let fee2 = results.items[0].fee2let fee3 = results.items[0].fee3let taxes = 1.05const totalPrice = (objectPrice + fee1 + fee2 + fee3)*taxes
return objectPrice;
}

Use the backend function computePrice in the frontend as well to display the price. That way price is computed in 1 place only which reduce the risk of mistake

let price =  parseInt($w("#textShowingPrice").text)

This returns NaN. Would this be due to the fact that my code computes the value by passing indices from an array ( results.items[0].price ), etc. and doesn’t first convert that index to a string or number?

I feel like I’m burying myself in logic here a bit and maybe overcomplicating things.

Using selections from several dropdowns to identify an item in a data collection; then targeting multiple fields from that item and adding them together; and finally updating a text element with the calculated value.

Thanks for providing an example for the backend and pointing out why calculations should be done in the backend.

Using this as a guide how would I pass the selected value from the dropdown on the frontend as a parameter for the computePrice() function?

Should I declare them by the corresponding dropdown ID (eg. foo = $w(#dropdown1).value) and then call that in .hasAll()?

Similar to this;

export function computePrice(foo, bar, baz) {
    let foo = $w("#dropdown1").value
    let bar = $w("#dropdown2").value
    let baz = $w("#dropdown3").value
    
    wixData.query("databaseCollection")
    .hasAll("foo", foo)
    .hasAll("bar", bar)
    .hasAll("baz", baz)
    

@matt5358 No you have to pass the value directly to the backend. Backend (wix servers) do not know anything about what’s in your user browser.

//frontend
...
let foo =$w("#dropdown1").value;
let bar =$w("#dropdown2").value;
let baz =$w("#dropdown3").value;
const payment = await createPaymentForFlight(foo, bar, baz)
const price = await computePrice(foo, bar, baz);

//use payment to open the payment popup
//use price to display the price in the UI
...

PS: I greatly suggest you check some examples on how to work with backend function on Wix and javascript function in general

@matt5358 You need to use onChange to get the right value. Create an onChange event then pass the String value to the variable when dropdown change.

Example:

let numberValue = 0;

$w("#dropdown").onChange((event) => {
    numberValue = parseInt($w("#dropdown").value);
})

If I wrote .text it’s wrong sorry about that it should be value :slight_smile: