Hello everyone, I am having some trouble adding a ...
# suitecommerce
t
Hello everyone, I am having some trouble adding a custom payment within my extension and was hoping someone could offer some advice. I am making an extension that sits in the payment selection template of my checkout and the idea is that if the customer chooses to use this payment method, the extension will add the custom payment to the transaction and then proceed to the review step. I have set up the custom payment within netsuite (it has the ID of 108) and am using the cart method addPayment() but when I use the cart method getPaymentMethods(), it returns an empty array. After adding the payment I use the checkout method setCurrentStep() to change to the review step, the URL seems to reflect that it is going to review, however the view is still displaying the payment select with no errors appearing. I have also attempted to use addPayment() to just add a credit card payment (just to see if it would work) and I got an error, TypeError: Cannot read property "internalid" from undefined (ssp_libraries.js#8149). Here is a snippet of my code (the creditcard payment details are commented out within the addPayment()):
Copy code
await cart.addPayment({
							payment_method: {
								internalid: '108'
								// type: 'creditcard',
								// creditcard: {
								// 	ccnumber: "5168441223630339",
								// 	ccname: "John Smith",
								// 	ccexpiredate: "11/1/2022",
								// 	expmonth: "11",
								// 	expyear: "2022"
								// }
							}
						});

						await cart.getPaymentMethods().then(function(pm){
							console.log('payment method', pm);
						});

						var nextStep = {};
						
						await checkout.getStepsInfo().then(async function(stepInfo){
							var steps = stepInfo;
							console.log('steps', steps);
							await checkout.getCurrentStep().then(function(step){
								var currentStep = step;
								console.log('current step', step);
								for(var i = 0; i < steps.length; i++){
									if(currentStep.url === steps[i].url){
										if(steps[i +1].show_step){
											nextStep = steps[i +1];
											break;
										}
										else{
											for(var j = i +1; j < steps.length; j++){
												if(steps[j].show_step){
													nextStep = steps[j];
													break;
												}
											}
											break;
										}
									}
								}
							});
						});

						await checkout.setCurrentStep({
							url: nextStep.url,
							step_url: nextStep.url,
							name: nextStep.name,
							show_step: true,
							state: 'Present',
							step_group_name: nextStep.step_group_name,
							modules: nextStep.modules
						});
Any help would be much appreciated! 🙂
p
i believe the backend doesn't understand the fact that you are not sending a payment method type.
Copy code
// type: 'creditcard',
this
in the past (19.1) i've had to customize the backend too for that.
t
I did specifiy a type originally, in netsuite I had the custom payment method's type as offline and I reflected that in my script, which also didn't work, then I saw in documentation the available types were paypal, creditcard, external_checkout, so i changed it to an external_checkout in netsuite and had that as the type within my script. also did not work. :(
p
I think you'll need to assign it a new type and work in the backend too.
Copy code
LiveOrderModel.setPaymentMethods = _.wrap(LiveOrderModel.setPaymentMethods, function (fn, data) {
    var certificateMethods;
    var methods;
    fn.apply(this, _.toArray(arguments).slice(1));
    certificateMethods = _.where(data.paymentmethods, { type: 'giftcertificate' });
    methods = _.difference(data.paymentmethods, certificateMethods);

    if (this.isSecure && methods && methods.length && ModelsInit.session.isLoggedIn2()) {
        _.each(methods, function (paymentmethod) {
            if (paymentmethod.type === 'payinstore') {
                ModelsInit.order.removePayment();

                try {
                    ModelsInit.order.setPayment({
                        paymentterms: '',
                        paymentmethod: Configuration.get('pickup.payInStorePaymentMethodID', '8')
                    });
                } catch (e) {
                    if (e && e.code && e.code === 'ERR_WS_INVALID_PAYMENT') {
                        ModelsInit.order.removePayment();
                    }
                    throw e;
                }
            }
        });
    }
});
this is my code for 19.1 the last time i had to do something like that
(it's sca backoffice suitescript)
t
great, thank you very much. I will give this a try.
p
I wouldn't use this in SC (suitecommerce) . But I'd use it in SCA. An update could break it otherwise. Take this code as inspiration only, things change between versions, and obviously the ids are for my case. The key is ModelsInit.order.setPayment
Copy code
LiveOrderModel.getPaymentMethods = _.wrap(LiveOrderModel.getPaymentMethods, function (fn, orderFields) {
    var paymentMethods = fn.apply(this, _.toArray(arguments).slice(1));

    if (
        orderFields.payment &&
        orderFields.payment.paymentmethod === Configuration.get('pickup.payInStorePaymentMethodID', '8')
    ) {
        paymentMethods.push({
            type: 'payinstore',
            name: 'Pay In Store',
            primary: true
        });
    }
    return paymentMethods;
});
this is the other piece you need, to let the frontend know there's the ability to select that payment type.
Good luck 😄
t
thanks again, I will let you know how I go 🙂