I've written a custom app which uses a PHP server for the back end and the bigcommerce checkout/cart sdk with JS for the front end.
Basically this is what I want to do:
Retrieve Rates using my php app and a 3rd party api (This works)
Display said rates as selectable options (This works)
Update the checkout and consignment (This works but not 100%)
Update the cart shipping method and total (This is where I am stuck)
After I get the rates from the PHP server, I dynamically build the list's HTML.
I randomly assign shipping method id's (As I have no idea how this gets generated but it appears to be fairly random)
When I click on a shipping option this code runs (Please note that 'option' is a variable within a foreach loop
console.dir(checkoutObj);
if(checkoutObj.consignments.length < 1){
console.log('no consign');
} else {
var selectedShipping = checkoutObj.consignments[0].selectedShippingOption;
selectedShipping.cost = parseFloat(option['grandtotmrkup']);
selectedShipping.description = option['CarrierName'] + '-' + option['CarrierService'];
selectedShipping.id = this.value;
selectedShipping.type = 'weight_based_shipping';
checkoutObj.consignments[0].shippingCost = parseFloat(option['grandtotmrkup']);
checkoutObj.shippingCostBeforeDiscount = parseFloat(option['grandtotmrkup']);
checkoutObj.shippingCostTotal = parseFloat(option['grandtotmrkup']);
console.log('updated checkout obj');
console.dir(checkoutObj);
var updated = service.updateCheckout(checkoutObj);
console.log('updated');
console.dir(state.data.getCheckout());
console.log('updating consignment');
console.dir(
service.updateConsignment({'id':consignID,'shippingOptionId':shippingMethodId})
);
console.dir(state.data.getConsignments());
When it runs service.updateConsignment I get the following response for the consignments section of the object:
"consignments": [
{
"id": "5f732875d039f",
"shippingCost": 0,
"handlingCost": 0,
"couponDiscounts": [],
"discounts": [],
"lineItemIds": [
"4f557702-4f9d-45ec-943a-c72ea963ccc7"
],
"selectedShippingOption": {
"id": "4dcbf24f457dd67d5f89bcf374e0bc9b",
"type": "freeshipping",
"description": "Free Shipping",
"imageUrl": "",
"cost": 0,
"transitTime": "",
"additionalDescription": ""
},
"shippingAddress": {
"firstName": "1",
"lastName": "1",
"email": "",
"company": "",
"address1": "1 street",
"address2": "",
"city": "MITCHAM",
"stateOrProvince": "Victoria",
"stateOrProvinceCode": "VIC",
"country": "Australia",
"countryCode": "AU",
"postalCode": "3132",
"phone": "",
"customFields": [],
"shouldSaveAddress": true
},
"availableShippingOptions": [
{
"id": "9ba45e71fe66e1cd757f022dcae331b0",
"type": "shipping_pickupinstore",
"description": "Pickup In Store",
"imageUrl": "",
"cost": 0,
"transitTime": "",
"isRecommended": false,
"additionalDescription": ""
},
{
"id": "4dcbf24f457dd67d5f89bcf374e0bc9b",
"type": "freeshipping",
"description": "Free Shipping",
"imageUrl": "",
"cost": 0,
"transitTime": "",
"isRecommended": true,
"additionalDescription": ""
}
]
}
],
I'm not sure if it's because my shipping options aren't in the Available Shipping Options Section of the object?
Does anyone know how I can get my shipping methods in there? Or is this being caused because I append the methods dyanmically via HTML?
I'm new to BC so please excuse any ignorance.
I don't think you're going to be able to inject a shipping option into the checkout this way, I think you'd need to look at using the Shipping Methods API in your PHP app and then the options should be available as per usual.
Related
I'm integrating Klarna in a sandbox environment that is tied to Adyen. I have followed the docs precisely but am having an issue where there is no "continue" button showing in the widget thus blocking the checkout process.
-EXPECTED-
-ACTUAL (MISSING BUTTON)-
Code to re create:
Post to: https://checkout-test.adyen.com/v67/payments
{
"merchantAccount": "MERCHANTLLC",
"reference": "123",
"paymentMethod": {
"type": "klarna_account"
},
"amount": {
"currency": "USD",
"value": 18210
},
"shopperLocale": "en_US",
"countryCode": "US",
"telephoneNumber": "1111111111",
"shopperEmail": "test#gmail.com",
"shopperName": {
"firstName": "John",
"lastName": "Doe"
},
"returnUrl": "http://someurl.com",
"lineItems": [
{
"quantity": 1,
"amountExcludingTax": "16900",
"taxPercentage": "775",
"description": "asdfasdf",
"id": "123",
"taxAmount": 1310,
"amountIncludingTax": "18210",
"productUrl": "http://producturl.com"
}
]
}
which returns the client_token: "ABC123". That token is then used to load the widget via the klarna docs:
window['Klarna']['Payments'].init({
client_token: 'ABC123'
})
window['Klarna']['Payments'].load({
container: '#klarna-payments-container',
payment_method_category: 'pay_over_time',
instance_id: "klarna-payments-instance"
},
function (res) {
console.log(res);
})
What is returned from the callback is {show_form: true} and the widget loads with the ACTUAL (MISSING BUTTON) picture above. What am i missing here?? I don't understand why I don't have a continue button showing up in the widget. This button is what then authorizes the user in Klarna, takes billing info, etc. Any help would be greatly appreciated! The goal is to get the 'Continue' button showing.
Answering my own question after speaking to the Klarna team. On the dev side you need to create your own button and call the 'Authorize' endpoint. Documentation can be found here: https://developers.klarna.com/documentation/klarna-payments/integration-guide/authorize/
I hope you guys are having a wonderful day.
I have set up a webhook in my woocommerce that sends JSON data to Google sheets. The webhook has been working great for months now, just today, I am having some trouble with it. I have tracked the issue to be in google sheets receiving the JSON data, but I don't know why this is happening.
Let me explain.
https://docs.google.com/spreadsheets/d/18G-yVDjYeccl6kznpZgSuRTysRMAu57pwY2oGf6-KWI/edit?usp=sharing
This is the google sheet, when it gets Woocommerce JSON data, it populates a new row.
The problem
Sometimes google sheets doesn't populate the row upon receiving a new order. The problem doesn't lie with woocommerce, because I have checked woocommerce with reqbin and the webhook fires with every order.
Furthermore, when I send requests from reqbin.com to my sheet, the sheet performs the operation successfully 5-6 out of 10 times. Other times it shows an error.
The Error
The error is due to google sheets not being able to parse JSON data, because the JSON data it receives 5 out of 10 times is not proper JSON data. Other 5 times, it is just as it should be. I have put a catch statement if the sheet is unable to parse JSON. Instead of appending new row with the parsed data, it appends the raw received data to the sheet.
It is clear now that there is some issue with google sheets handling that JSON data because when the same data is sent from reqbin.com to webhook.site, it is perfectly as it should be 10/10 times.
How to reproduce the issue
Open this google sheet. https://docs.google.com/spreadsheets/d/18G-yVDjYeccl6kznpZgSuRTysRMAu57pwY2oGf6-KWI/edit?usp=sharing
Open reqbin.com and webhook.site, and send the following JSON from reqbin.com to webhook.site 10 times to see if any kind of error occurs.
{ "id": 47222, "parent_id": 0, "status": "processing", "currency": "PKR", "version": "5.1.0","prices_include_tax": false, "date_created": "2021-06-10T01:23:46", "date_modified": "2021-06-10T01:23:46", "discount_total": "0", "discount_tax": "0", "shipping_total": "150", "shipping_tax": "0", "cart_tax": "0", "total": "1850", "total_tax": "0", "customer_id": 0, "order_key": "wc_order_7gIuR7px6MX9C", "billing": { "first_name": "Name", "last_name": "", "company": "", "address_1": "Address", "address_2": "", "city": "City", "state": "", "postcode": "", "country": "PK", "email": "email#email.com", "phone": "1234" }, "shipping": { "first_name": "Name", "last_name": "", "company": "", "address_1": "Address", "address_2": "", "city": "City", "state": "", "postcode": "", "country": "Country" }, "payment_method": "cod", "payment_method_title": "Cash on delivery", "transaction_id": "", "customer_ip_address": "8.8.8.8", "customer_user_agent": "Mozilla/5.0 (Linux; Android 11; M2102J20SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.88 Mobile Safari/537.36", "created_via": "checkout", "customer_note": "", "date_completed": null, "date_paid": null, "cart_hash": "64d834c72eecc8e32b9d83fd67d10d9c", "number": "47222", "meta_data": [ { "id": 869388, "key": "_shipping_calculator", "value": "" }, { "id": 869389, "key": "is_vat_exempt", "value": "no" }, { "id": 869391, "key": "_wfacp_report_data", "value": { "wfacp_total": "0.00" } }, { "id": 869392, "key": "_woofunnel_cid", "value": "4" }, { "id": 869393, "key": "_wfacp_post_id", "value": "24852" }, { "id": 869394, "key": "_wfacp_source", "value": "https://website.com/checkouts/checkout-page/" }, { "id": 869395, "key": "_wfacp_timezone", "value": "Asia/Karachi" }, { "id": 869396, "key": "order_comments", "value": "" }, { "id": 869412, "key": "_new_order_email_sent", "value": "true" }, { "id": 869424, "key": "_woofunnel_custid", "value": "4" }, { "id": 869425, "key": "_pys_purchase_event_fired", "value": "1" }, { "id": 869426, "key": "_wfob_stats_ids", "value": [] }, { "id": 869427, "key": "_wfocu_thankyou_visited", "value": "yes" } ], "line_items": [ { "id": 35114, "name": "MTECH Ultra Resilient Knife", "product_id": 11074, "variation_id": 0, "quantity": 1, "tax_class": "", "subtotal": "1700", "subtotal_tax": "0", "total": "1700", "total_tax": "0", "taxes": [], "meta_data": [], "sku": "", "price": 1700, "parent_name": null } ], "tax_lines": [], "shipping_lines": [ { "id": 35115, "method_title": "Fast Shipping (2-4 Days)", "method_id": "flat_rate", "instance_id": "1", "total": "150", "total_tax": "0", "taxes": [], "meta_data": [ { "id": 275053, "key": "Items", "value": "MTECH Ultra Resilient Knife × 1", "display_key": "Items", "display_value": "MTECH Ultra Resilient Knife × 1" } ] } ], "fee_lines": [], "coupon_lines": [], "refunds": [], "date_created_gmt": "2021-06-09T20:23:46", "date_modified_gmt":"2021-06-09T20:23:46", "date_completed_gmt": null, "date_paid_gmt": null, "currency_symbol": "₨","_links": { "self": [ { "href": "https://website.com/wp-json/wc/v3/orders/47222" } ],"collection": [ { "href": "https://website.com/wp-json/wc/v3/orders" } ] } }
Now send the same data to the following google sheet to see if it appends the row correctly each time.
https://script.google.com/macros/s/AKfycbxupm9bje86F4PQQkyys_LWtXs_kj279R0ipgnZ-cLd7aiEADf1AN_prhk28vOPW9JsRQ/exec
How do I solve the issue? Please let me know if you need any more information. Thanks.
Edit:
Instead of getting a full JSON body like mentioned above, the google sheets seems to be getting the following JSON.
{contextPath=, queryString=, parameter={}, postData=FileUpload, parameters={}, contentLength=3981.0}
I would like to know why the google sheets default parameter (e) contains this instead of a full JSON body sent to it.
Edit # 2
I would like to know why the google sheets default parameter (e) contains this instead of a full JSON body sent to it.
This is because (e) has a body which will always contain those parameters. The error is due to Google Sheets receiving an empty JSON body. I am still unable to understand why this happens. When I send the same JSON to API testing sites, they always receive full JSON body. Google sheets, in some cases, does not. Why is that?
I managed to solve the issue with some trial and error. For anyone facing the same issue in the future, here is what worked for me.
I was using e.postData.contents to get the JSON body but this seems to have stopped working, which was causing the JSON body to be empty. I tried e.postData.getDataAsString(); which seems to be working just fine and the issue has been resolved.
In Razorpay I have created an order with some amount, and also completed the payment transaction for the order, but now I need to transfer the amount to the linked account using the route, but the issue is when I use their transfer with order API from postman(which they provided in the docs). It's giving an error. What do I need to do in order to link it to the transfer and then complete the payment?
{
"error": {
"code": "BAD_REQUEST_ERROR",
"description": "The amount field is required.",
"source": "business",
"step": "payment_initiation",
"reason": "input_validation_failed",
"metadata": {},
"field": "amount"
}
}
But I have provided the amount field in the body of the request, here is what the body looks like
{
"amount": 10000, // this is the smallest unit(also tried with the larger unit)
"currency":"INR",
"transfers": [
{
"account": "acc_hhsk",
"amount": 10000,
"currency": "INR",
"notes": {
"branch": "Chess Program",
"name": "Nilesh Kumar"
},
"linked_account_notes": [
"branch"
],
"on_hold": false,
"on_hold_until": null
}
]
}
Before this, I have successfully generated the order_id. Please help me find how to link order_id with the transfer.
Pass like below it will work.
use Razorpay\Api\Api;
$transfer['transfers'][0]['account'] = "acc_IGd0hn6ZZ6khPr";
$transfer['transfers'][0]['amount'] = "800000";
$transfer['transfers'][0]['currency'] = "INR";
$notes['name'] = "sshhss";
$notes['roll_no'] = "IEC2011025";
$transfer['transfers'][0]['notes'] = $notes;
$transfer['transfers'][0]['linked_account_notes'] = ['roll_no'];
$transfer['transfers'][0]['on_hold'] = "1";
// $transfer['transfers'][0]['on_hold_until'] = "1671222870";
$paymentId = "Pay_heeu7333gg";
$api = new Api('API_KEY', 'API_SECRET');
$payment = $api->payment->fetch($paymentId)->transfer($transfer);
So this is my case:
In my angular 8 application i create invoices. this is an invoice object:
{
"_id": {
"$oid": "5ea9ad58f65d8d49841362bd"
},
"details": [
{
"_id": "5ea1eff27a1fcb29c4e7d1b6",
"Client": "test",
"km": 88,
"Subject": "test",
"Location": "test",
"StartTime": "2020-04-27T09:00:00.000Z",
"EndTime": "2020-04-27T17:00:00.000Z",
"IsAllDay": false,
"StartTimezone": null,
"EndTimezone": null,
"Description": "oekfokef",
"RecurrenceRule": "FREQ=DAILY;INTERVAL=1;COUNT=5;",
"Id": 2,
"CreatedBy": "bob"
},
{
"_id": "5ea1f36297a9a315bc8ed078",
"Client": "test",
"km": 88,
"Subject": "ewfwefwe",
"Location": "fwefwefwefewfwefwef",
"StartTime": "2020-04-20T09:00:00.000Z",
"EndTime": "2020-04-20T17:00:00.000Z",
"IsAllDay": false,
"StartTimezone": null,
"EndTimezone": null,
"Description": "wefwefewfwef",
"RecurrenceRule": "FREQ=DAILY;INTERVAL=1;COUNT=5;",
"Id": 3,
"CreatedBy": "bob"
},
{
"_id": "5ea1f38d97a9a315bc8ed083",
"Client": "test2",
"km": 38,
"Subject": "test",
"Location": "test",
"StartTime": "2020-05-04T09:00:00.000Z",
"EndTime": "2020-05-04T16:00:00.000Z",
"IsAllDay": false,
"StartTimezone": null,
"EndTimezone": null,
"Description": "test",
"RecurrenceRule": "FREQ=DAILY;INTERVAL=1;COUNT=5;",
"Id": 4,
"CreatedBy": "bob"
}
],
"client": "Robin",
"hoursWorked": 75,
"kmsTravelled": 880,
"invoiceDate": "2020-04-29T16:37:44.948Z",
"paid": "false",
"subTotal": 3917.2,
"travelexpenses": 167.2,
"tax": 879.7,
"hoursCosts": 3750,
"total": 4796.9,
"createdBy": "bob",
"__v": 0
}
But during the use of the application, certain properties change value, like hoursWorked, total, kmTravelled, hourCosts and details. The updated objects get printed to the console. So whenever the user opens the component, i want it to post the whole object, but if an invoice with that Client name alread exists , only update those properties of each invoice per client.
the updated object is this.invoice:
this.invoice = {
client: element.Client,
hourCosts: (element.difference)*this.Client.price,
hoursWorked: (element.difference),
kmsTravelled: element.km,
travelexpenses: this.Client.kmPrice* element.km,
subTotal: (this.Client.kmPrice* element.km) + ((element.difference)*this.Client.price),
total: ((this.Client.kmPrice* element.km) + ((element.difference)*this.Client.price)) + ((this.Client.kmPrice* element.km)+((element.difference)*this.Client.price) * this.tax/100),
createdBy: this.userName,
details: this.details
}
So how do I go about this? Sorry for a quite vague question, but i stuck with this quite a while now. If you need more info please let me know
You could query by 'id' to search for specific values that have changed with something like: db.getCollection('hourCosts').find({_id:'5ea9ad58f65d8d49841362bd'})
Searching in a collection by id with .find() will be efficient. There's a really helpful mongoose doc page here.
Also, just clarifying, you're posting the full customer schema if the name is unique, otherwise updating the relevant invoices by 'client', is that correct? The doc page linked should be useful for most query types and you can create additional mongoose schemas for some added granularity in what content you change.
you can use mongoDB $set in the update command, example:
db.city.update({_id:ObjectId("584a13d5b65761be678d4dd4")}, {$set: {"citiName":"Jakarta Pusat"}})
make sure you are passing the _id as ObjectId
https://www.djamware.com/post/58578ab880aca715e80d3caf/mongodb-simple-update-document-example
I'm using ember rc3 and ember-data 12 (sha e324f0e) (basically the files recommended in the guides). I have 2 models set up as follows:
App.User = DS.Model.extend({
username: DS.attr('string'),
playerType: DS.attr('string'),
cars: DS.hasMany('App.Car')
})
App.Car = DS.Model.extend({
name: DS.attr('string'),
thumb: DS.attr('string'),
user: DS.belongsTo('App.User')
})
The json returned is
{
"cars": [
{
"id": "50ace47234fa7557403e7f02",
"name": "Dodge Charger SRT8",
"thumb": "/static/images/carthumbs/18331.png",
"user_id": "502a754b34fa75280c000a7e"
},
{
"id": "508668cc34fa753b78784ca2",
"name": "BMW M3 Coup\u00e9",
"thumb": "/static/images/carthumbs/23250.png",
"user_id": "502a754b34fa75280c000a7e"
},
{
"id": "50c7545334fa750ab8cb3ac2",
"name": "BMW Z4 M Coup\u00e9",
"thumb": "/static/images/carthumbs/7618.png",
"user_id": "502a754b34fa75280c000a7e"
},
{
"id": "50adf64c34fa750bb036121e",
"name": "2013 Ford Shelby GT500\u2122",
"thumb": "/static/images/carthumbs/24824.png",
"user_id": "502a754b34fa75280c000a7e"
}
],
"user": {
"id": "502a754b34fa75280c000a7e",
"car_ids": [
"50ace47234fa7557403e7f02",
"508668cc34fa753b78784ca2",
"50c7545334fa750ab8cb3ac2",
"50adf64c34fa750bb036121e"
],
"player_type": "Standard Player",
"username": "WillMckenzie"
}
}
Everything seems to load fine if I call App.User.find("502a754b34fa75280c000a7e"), but when I try and access the cars property on the user it triggers a second http request to the cars api route. It was my understanding that this shouldn't be necessary, and if I change the ids to basic ints, it doesn't. As I'm using Mongo as my DB my ids have to be in this string format.
Any suggestions as to what I'm doing wrong?
Cheers
Will
Here's the answer so people don't have to dig through the comments:
"I had one car id listed that wasn't in the list of cars returned. They're grabbed slightly differently and I obviously had a bad record in there. This meant it always thought it needed to reload that record so would keep requesting. Obviously when I was faking the integer ids it was masking this." - OiNutter