Razorpay Integration with Ionic 4 getting Bad request error - ionic4

I have used razorpay-cordova plugin to perform payment for Rozar pay but I am getting Bad request "The id provided does not exist". But I am using my test key id and that is very correct.
payWithRozarPay(invoice: any) {
const options = {
description:
'Buy ' + invoice.coin_amount + ' amount credit for quicklegalsolutions',
currency: 'INR',
key: 'rzp_test_Qtzsbri8xV2oIa',
order_id: invoice.inv_code,
amount: invoice.amount * 100,
name: 'Quick Legal Solutions',
prefill: {
email: invoice.user.email,
contact: invoice.user.mobile,
name: invoice.user.name
},
theme: {
color: '#F37254'
}
};
console.log(options);
// tslint:disable-next-line: only-arrow-functions
const successCallback = function(success: any) {
alert('payment_id: ' + success.razorpay_payment_id);
console.log('payment_id: ' + success.razorpay_payment_id);
};
// tslint:disable-next-line: only-arrow-functions
const cancelCallback = function(error: any) {
alert(error.description + ' (Error ' + error.code + ')');
console.log(error);
};
RazorpayCheckout.on('payment.success', successCallback);
RazorpayCheckout.on('payment.cancel', cancelCallback);
RazorpayCheckout.open(options);
}

remove the 'order_id: invoice.inv_code' from description

You are correct #sayak
Actually on the field order_id the id used when you the order flow to generate a new order from razorpay api that is /order that is used,
Most probably you are not using their order flow, so that's why the id you are sending does not exist on their records.
If you using their flow for managing order you should send the order_id that you are received while generating the order

Related

SuiteScript Workflow Action-how to add error handling

I have a workflow action script that is supposed to search for a string in an email message body (the string being for the document number--this is stored in a field with the id 'custevent_case_creation') and return the transaction record id.
The script:
/**
*#NApiVersion 2.x
*#NScriptType WorkflowActionScript
* #param {Object} context
*/
define(["N/search", "N/record"], function (search, record) {
function onAction(context) {
var recordObj = context.newRecord;
var oc_number = recordObj.getValue({ fieldId: "custevent_case_creation" });
var s = search
.create({
type: "salesorder",
filters: [
search.createFilter({
name: "tranid",
operator: search.Operator.IS,
values: [oc_number],
}),
],
columns: ["internalid"],
})
.run()
.getRange({
start: 0,
end: 1,
});
log.debug("result set", s[0].id);
return s[0].id;
}
return {
onAction: onAction,
};
});
This works as expected when there is a valid document number used in the email message.
However, there are two scenarios where that won't be the case:
there is no document number referenced in the original email (and therefore, the field "custevent_case_creation" will be blank)
the document number referenced is incorrect and there is no transaction with that document number in the system
I am trying to add some form of error handling to deal with these two scenarios though I can't find anything that works. Where should the error handling be in this script?
Should it be an if/else statement?
So far I have tried:
adding if{s.length>0);
adding a condition in the workflow itself so that the custom action from the workflow action script doesn't occur if the field for custevent_case_creation is blank
-
The error message I am getting is:
org.mozilla.javascript.EcmaError: TypeError: Cannot read property "id" from undefined (/SuiteScripts/sdf_ignore/Workflow Action Lookup SO.js#41)
EDIT:
The working code
/**
*#NApiVersion 2.x
*#NScriptType WorkflowActionScript
* #param {Object} context
*/
define(["N/search", "N/record"], function (search, record) {
function onAction(context) {
try {
var recordObj = context.newRecord;
var oc_number = recordObj.getValue({
fieldId: "custevent_case_creation",
});
var s = search
.create({
type: "salesorder",
filters: [
search.createFilter({
name: "tranid",
operator: search.Operator.IS,
values: [oc_number],
}),
],
columns: ["internalid"],
})
.run()
.getRange({
start: 0,
end: 1,
});
log.debug("result set", s[0].id);
return s[0].id;
} catch (error) {
log.debug(
error.name,
"recordObjId: " +
recordObj.id +
", oc_number:" +
oc_number +
", message: " +
error.message
);
}
}
return {
onAction: onAction,
};
});
Try wrapping the contents of you onAction function with try/catch. More info on try/catch can be found here on W3Schools.
try {
//your working code for onAction function
var recordObj = context.newRecord;
var oc_number = recordObj.getValue({ fieldId: "custevent_case_creation" });
var s = search.create({
type: "salesorder",
filters: [
search.createFilter({
name: "tranid",
operator: search.Operator.IS,
values: [oc_number]
})
],
columns: ["internalid"]
})run().getRange({
start: 0,
end: 1,
});
log.debug("result set", s[0].id);
return s[0].id;
} catch(e){
log.debug(e.name,'recordObjId: '+ recordObj.id +', oc_number:'+ oc_number +', message: ' + e.message); //if e.name is empty try e.title
//you can add additional steps here if desired, i.e. send an email, display an alert, etc.
}

Apollo/graphql request result buffered in vuejs

In a Vue component controlling users subsciption to newsletters, I have the fellowing code:
async newSubscriber(event) {
// Validate email
//---------------
if (!this.isEmailValid(this.subscriber_email))
this.subscribeResult = "Email not valid";
else {
// If valid, check if email is not already recorded
//-------------------------------------------------
let alreadyRecorded = false;
let recordedEmails = await this.$apollo.query({ query: gql`query { newslettersEmails { email } }` });
console.log('length ' + recordedEmails.data.newslettersEmails.length);
console.log(recordedEmails.data.newslettersEmails);
for (let i = 0; !alreadyRecorded && i < recordedEmails.data.newslettersEmails.length; i++)
alreadyRecorded = this.subscriber_email === recordedEmails.data.newslettersEmails[i].email;
if (alreadyRecorded)
this.subscribeResult = "Email already recorded";
else {
// If not, record it and warn the user
//------------------------------------
this.$apollo.mutate({
mutation: gql`mutation ($subscriber_email: String!){
createNewslettersEmail(input: { data: { email: $subscriber_email } }) {
newslettersEmail {
email
}
}
}`,
variables: {
subscriber_email: this.subscriber_email,
}
})
.then((data) => { this.subscribeResult = "Email recorded"; })
.catch((error) => { this.subscribeResult = "Error recording the email: " + error.graphQLErrors[0].message; });
}
}
}
At the very first email subscription test, $apollo.query returns me the correct number of emails already recorded (let's say, 10) and record the new subscriber email. But if I try to record a second email without hard refreshing (F5) the browser, $apollo.query returns me the exact same result than the first time (10), EVEN IF the first test email has been correctly recorded by strapi (graphql palyground showns me the added email with the very same query!). Even if I add ten emails, apollo will always return me what it got during its first call (10 recorded emails), as if it uses a buffered result. Of course, that allows Vue to record several times the same email, which I obviously want to avoid!
Does it speaks to anyone ?
After a lot of Google digging (giving the desired results by simply changing in my requests, at the end, "buffering" by "caching" !), I understood that Apollo cache its queries by default (at least, in the configuration of the Vue project I received). To solve the problem I just added "fetchPolicy: 'network-only'" to the query I make:
let recordedEmails = await this.$apollo.query({
query: gql`query { newslettersEmails { email } }`,
});
became
let recordedEmails = await this.$apollo.query({
query: gql`query { newslettersEmails { email } }`,
fetchPolicy: 'network-only'
});
And problem solved ^^

How to implement Ngx-Datatable server side pagination if pagination is not zero based

I am trying to implement server-side pagination in angular 5 based web app.
Problem is the API requires pagination to start from index 1 whereas the library "ngx-datatable" pagination is 0 based.
Here's my current implementation:
mycomponent.html
<ngx-datatable
#usersTable
class='material text-centered'
[rows]='users'
[columns]="usersColumn"
[columnMode]="'force'"
[headerHeight]="50"
[footerHeight]="50"
[rowHeight]="'auto'"
[externalPaging]="true"
[offset]="page.offset"
[limit]="page.pageSize"
[count]="page.totalElements"
(page)='fetchList($event)'>
</ngx-datatable>
mycomponent.ts
page: any = {
offset: 0,
pageNumber: 1,
pageSize: 10,
totalElements: '',
sortBy: "id",
sortOrder: "desc"
};
ngOnInit() {
this.usersColumn = [
{
name: 'S.NO',
prop: 'sno'
},
{
name: 'First Name',
prop: 'firstName'
},
{
name: 'Last Name',
prop: 'lastName'
},
{
name: 'Email',
prop: 'email',
width: 200
},
{
name: 'Action',
cellTemplate: this.action
}
];
this.fetchList({ offset: 0 });
}
generateSerialNo(pageNo, size, i) {
const index = i + 1;
return pageNo == 1 ? index : (pageNo - 1) * size + index;
}
fetchList(pageInfo) {
this.page.pageNumber = pageInfo.offset + 1;
const { pageNumber, pageSize, sortBy, sortOrder } = this.page);
this.ListService.fetchList(pageNumber, pageSize, sortBy, sortOrder).subscribe(
success => {
if (success && !success['isError']) {
const responseObj = success['responseObject'];
if (responseObj) {
const List = responseObj.content || [];
const { totalElements } = responseObj;
this.users = List.map((item, i) => {
// set serial no. for user in current iteration
const serialNumber = this.generateSerialNo(this.page.pageNumber, this.page.pageSize, i);
return { sno: serialNumber, ...item };
});
this.page.totalElements = totalElements;
}
} else {
this.toastr.error(success['message'], 'Oops!');
}
},
errorResp => {
const error = errorResp['error'];
this.toastr.error(error['message'], 'Oops!');
}
);
Now Say, there's an action column in the table which consists of buttons to block or unblock user which on click calls a function as follows:
blockUnblockUser(toBlock: boolean) {
this.ListService.blockUnblockUser(toBlock, this.selectedUser.id).subscribe(
success => {
if (success && !success['isError']) {
this.fetchList(this.page);
this.utilService.closeModal();
this.toastr.success(success['message'], 'Success!');
} else {
this.utilService.closeModal();
this.toastr.error(success['message'], 'Oops!');
}
},
errorResp => {
const error = errorResp['error'];
this.utilService.closeModal();
this.toastr.error(error['message'], 'Oops!');
});
}
Here's the problem. On page load, I get my list for page number one and page number one is the active page. Now Click on page number 2, in the request param of API this is what goes:
list?pageNumber=2&pageSize=10&sortBy=id&sortOrder=desc
and in response, I get 3 data for page number 2 with 3 items.
Now if I click on the action button to either block or unblock particular user this is what sent in request params:
list?pageNumber=1&pageSize=10&sortBy=id&sortOrder=desc
and in response, I get data based on the page number 1 with 10 items.
but this time the active page in pagination is still "2"?
Please let me know where I am making mistake and how do I fix this. The backend team cannot make the pagination zero-based index for some reason.

Express js + Sequelize and hook

I am developping an application where I need to make extra validation on creating an object.
I tried using hooks and the beforeValidate function, but it's not working. I'm trying to fail the validation if the value submitted is greater than the value from the db (computed value based on custom query).
Transaction.beforeValidate(function(transaction, options) {
sequelize.query(
'SELECT SUM(IF(type = "buy", number_of_shares, number_of_shares * -1)) as remaining FROM transactions WHERE account_id = $account_id',
{
bind: {
account_id: req.body.account_id
},
type: sequelize.QueryTypes.SELECT
}
).then(result => {
if (req.body.type == "sell" && result.remaining < req.body.number_of_shares) {
throw error('Number of remaining shares is less than what you are trying to sell.') // psudeo code
}
}).then(result => {
return sequelize.Promise.resolve(user);
})
})
You're missing a return before sequelize.query(.
return sequelize.query(

Facing some issue to print the API response values in one sentence

I am trying to assert and print the response, for that need help.
Below is response body:
{
"createdIncidents":[
{
"incidentRef":"I0000000",
"personName":"API API",
"personType":"Patient"
},
{
"incidentRef":"I0000000",
"personName":"Ballarat HelpDesk",
"personType":"Staff"
},
{
"incidentRef":"I0000000",
"personName":"test api",
"personType":"Visitor"
},
{
"incidentRef":"I0000000",
"personName":null,
"personType":"Hazard"
}
]
}
I am trying to print incidentRef and personType together in a string.
For that, I am using this code:
var data = JSON.parse(responseBody);
data.createdIncidents.forEach(function(incident, personT) {
var personType = "personType" + personT.personType;
var incidents = "incidentRef" + incident.incidentRef;
var pt = tests["incidents created for " + personType ] = 'personType';
var inc = tests["incidents number is " + incidents] = 'incidents';
tests["incidents created for" +inc && + pt ];
});
Here it is not reading the second items inside the function.
In a separate function declaration it works fine.
I want to print it as:
"incidentRef": "I0000000 is created for "personType": "Hazard""
This would log each item from the createdIncidents array to the console - Unsure what you're actually trying to assert against though:
_.each(pm.response.json().createdIncidents, (arrItem) => {
console.log(`Incident Ref: ${arrItem.incidentRef} is created for Person Type: ${arrItem.personType}`)
})
Given your response data, this would be the output:
Incident Ref: I0000000 is created for Person Type: Patient
Incident Ref: I0000000 is created for Person Type: Staff
Incident Ref: I0000000 is created for Person Type: Visitor
Incident Ref: I0000000 is created for Person Type: Hazard
This could be wrapped in a pm.test() and the different items can be asserted against using the pm.expect() syntax.
This is very basic and is very hardcoded but it would check the data in your example:
pm.test('Check the response', () => {
_.each(pm.response.json().createdIncidents, (arrItem) => {
pm.expect(arrItem.incidentRef).to.equal("I0000000")
pm.expect(arrItem.personType).to.be.oneOf(['Patient','Staff','Visitor','Hazard'])
console.log(`Incident Ref: ${arrItem.incidentRef} is created for Person Type: ${arrItem.personType}`)
})
})