solidity reverse auction logic? - solidity

I am writing reverse auction with solidity and somewhat logic is confusing.
In regular auction, Seller make an auction with item, buyer (msg.sender) bids on the item, that bid amount will transfer to the smart contract, when auction is end, winning bid goes to the seller and other non-winning bid get refunded to the non-winners' account.
In reverse auction, Buyer create the auction, potential seller offer(bid) the price, lowest bid amount get selected and buyer (auction creator) will transfer money to the final offerer (bid winner with lowest price offer).
what i thought was that simply change the initial buyer and seller compare to the regular auction but it does not work
if (msg.value > winningBid) {
pendingReturns[msg.sender] += msg.value;
auctionWinner = msg.sender;
winningBid = msg.value;
emit RegularBidding(msg.sender, msg.value);
}
is the regular auction bidding logic (which works fine)
if (msg.value < winningBid) { // since winner is the one who offers the lowest price
pendingReturns[product.buyer] += msg.value; // when offer is made, buyer send money to the smart contract and get refunded later except for the winning offer amount
auctionWinner = msg.sender; // auctionWinner is the offerer (I think this line is wrong)
winningBid = msg.value;
emit ReverseBidding(product.buyer, msg.value); // buyer transfer the value to the seller
}
I know this code is wrong and logic is a bit confusing to me since msg.sender is totally opposite and buyer has to deposit money to the smart contract and get refunded later.

Related

Using OptaPlanner to solve a Vehicle Routing Problem with Time Windows

Hello OptaPlanner community.
I am developing a Rest API to plan the routes of a fleet of vehicles. Looking for a tool that would help me I found Optaplanner, and I have seen that it has several success stories. In a first stage I made a planning taking into account the fastest distance and the capacity of the vehicle to cover all its visits. And I got the results I expected. Now I'm planning for time windows of visits and deposits, but I'm not successful yet.
Requirements
R1- I have a fleet of vehicles. Each vehicle has a capacity and its deposit and this deposit has a window of time. From the example of OptaPlanner for VRP I have only made a variation on the capacity that I handle as a float. As I understand it, all the vehicles in the OptaPlanner example are moved for a single depot. In my case, each vehicle has its own depot, each vehicle has its own fixed depot, and it is possible that several vehicles have the same depot.
R2- I have the visits (delivery services). Each visit has a demand and a window of time. From the example of OptaPlanner for VRP I have only made one modification regarding the demand that I handle it as a type "float".
In this process of adding this variant with TW to my routing problem I have some doubts and problems since I have not obtained a viable solution to my problem by applying TW:
1- I understand that I do not need to make modifications to the OptaPlanner example so that each vehicle cannot transport more items than its capacity. I only need to adjust the constrint provider so that the calculation is on float. I would like to know if I am right ? and on the other hand How I can manage the capacities and demands with dimensions?, in OptaPlanner it is a number but I need to manage it as volume and weight.
In the OptaPlanner domain I modified the variables "capacity" from vehicle and "demand" from visit, both to type "float".
Constraint vehicleCapacity(ConstraintFactory constraintFactory) {
return constraintFactory.from(PlanningVisit.class)
.groupBy(PlanningVisit::getVehicle, sumBigDecimal(PlanningVisit::getDemand))
.filter((vehicle, demand) -> demand.compareTo(vehicle.getCapacity()) > 0)
.penalizeLong(
"vehicle capacity",
HardSoftLongScore.ONE_HARD,
(vehicle, demand) -> demand.subtract(vehicle.getCapacity()).longValue());
}
2- In the OptaPlanner example I understand that the TW is a long that multiplies by a thousand, but I do not know if this long expresses an hour or date, or if it is just the hour converted into minutes and multiplied by a thousand.
What I am doing is converting the TW to minutes and multiplied by a thousand, for example if it is 8am, the ready time is a log equal to '480000'.
In the case of the service duration, I do not multiply it by 1000, I always treat it as 10 minutes. Am I doing the conversion correctly? , is this the long that OptaPlanner expects?
3- I understand that using the example of OptaPlanner for time windows I can solve this requirement (R2), without making variations, however for some reason that I can not find is not giving me back a feasible solution. It returns me for example: time spent (5000), best score (-3313987hard/-4156887soft).
I have thought that the error could be in the conversion of the dates of the time window or maybe some hard constraint that I lack, because the arrival times of the visits do not adapt to the time windows defined for visits nor for deposits.
For example:
I have 4 visits with time windows, 2 in the morning (visit 2 and visit 4) and 2 in the afternoon (visit 1 and visit 3).
I have two vehicles, vehicle 1 leaves a depot 1 that has a time window in a morning schedule and the other vehicle leaves a depot 2 that has a time window in an afternoon schedule.
So I expect vehicle 1 to conduct the visits that have a time window in the morning and vehicle 2 to conduct the visits that have a time window in the afternoon: [vehicle 1: {visit 2, visit 4}, vehicle 2: {visit 1, visit 3}]
I must be doing something very wrong, but I can't find where, not only does it not meet the TW of the deposit, but the arrival times of each visit exceed the defined TW. I don't understand why I get such big arrival times, that even exceed the defined limit for 1 day (all arrival times are over 1440000 = 1400min = 24 = 12am), that is, they arrived after this time.
This is the result I have obtained: score (-3313987hard/-4156887soft)
Route 1 referring to the route followed by vehicle 1
Vehicle 1
Depot 1 with TW (8:00 a 13:00)
ready_time: 480000
due_time: 780000
Visit 2 (8:30 a 12:30)
ready_time: 510000
due_time: 750000
service_duraration 10 = 10
arrival_time: 1823943
departure_time: 1833943
Visit 4 (9:30 a 12:30)
ready_time: 570000
due_time: 750000
service_duraration 10
arrival_time: 1739284
departure_time: 1739294
Visit 3 (14:40 a 15:30)
ready_time: 880000
due_time: 930000
service_duraration 10
arrival_time: 1150398
departure_time: 1150408
Route 2 referring to the route followed by vehicle 2
Vehicle 2
Depot 2 with TW (12:00 a 17:00)
ready_time: 720000
due_time: 1020000
Visit 1 (14:00 a 16:30)
ready_time: 840000
due_time: 990000
service_duraration 10 = 10
arrival_time: 2523243
departure_time: 2523253
This is my code, it can give you a better context.
This is my VariableListerner for updating the shadow variable 'arrival time'. I have not made any modifications, however the arrival times returned to me for each visit do not comply with the TW.
public class ArrivalTimeUpdatingVariableListener implements VariableListener<PlanningVisit> {
...
protected void updateArrivalTime(ScoreDirector scoreDirector, TimeWindowedVisit sourceCustomer) {
Standstill previousStandstill = sourceCustomer.getPreviousStandstill();
Long departureTime = previousStandstill == null ? null
: (previousStandstill instanceof TimeWindowedVisit)
? ((TimeWindowedVisit) previousStandstill).getDepartureTime()
: ((TimeWindowedDepot) ((PlanningVehicle)
previousStandstill).getDepot()).getReadyTime();
TimeWindowedVisit shadowCustomer = sourceCustomer;
Long arrivalTime = calculateArrivalTime(shadowCustomer, departureTime);
while (shadowCustomer != null && !Objects.equals(shadowCustomer.getArrivalTime(),
arrivalTime)) {
scoreDirector.beforeVariableChanged(shadowCustomer, "arrivalTime");
shadowCustomer.setArrivalTime(arrivalTime);
scoreDirector.afterVariableChanged(shadowCustomer, "arrivalTime");
departureTime = shadowCustomer.getDepartureTime();
shadowCustomer = shadowCustomer.getNextVisit();
arrivalTime = calculateArrivalTime(shadowCustomer, departureTime);
}
}
private Long calculateArrivalTime(TimeWindowedVisit customer, Long previousDepartureTime) {
if (customer == null || customer.getPreviousStandstill() == null) {
return null;
}
if (customer.getPreviousStandstill() instanceof PlanningVehicle) {
// PreviousStandstill is the Vehicle, so we leave from the Depot at the best suitable time
return Math.max(customer.getReadyTime(),
previousDepartureTime + customer.distanceFromPreviousStandstill());
}
return previousDepartureTime + customer.distanceFromPreviousStandstill();
}
}
And this service is where I build the domain entities from the data stored in the database (find). This TimeWindowedVehicleRoutingSolution is the one I use in the solver.
public TimeWindowedVehicleRoutingSolution find(UUID jobId) {
//load VRP from DB
RoutingProblem byJobId = routingProblemRepository.findVRP(jobId);
Set<Vehicle> vehicles = byJobId.getVehicles();
Set<Visit> visits = byJobId.getVisits();
//building solution
List<PlanningDepot> planningDepots = new ArrayList<>();
List<PlanningVehicle> planningVehicles = new ArrayList<>();
List<PlanningVisit> planningVisits = new ArrayList<>();
vehicles.forEach(vehicle -> {
//submit to planner location of the deposit, add to matrix for calculating distance
PlanningLocation planningLocation =
optimizer.submitToPlanner(vehicle.getDepot().getLocation());
//Depot, Vehicle and Visit are my persistence JPA entities, they are not the OptaPlanner
domain entities.
//The OptaPlanner domain entities are: PlanningVehicle, PlanningDepot and PlanningVisit
//I build the entities of the optaplanner domain from my persistence entities
Depot depot = vehicle.getDepot();
TimeWindowedDepot timeWindowedDepot = new TimeWindowedDepot();
TimeWindowedDepot timeWindowedDepot = new TimeWindowedDepot(depot.getId(),
planningLocation, depot.getStart(), depot.getEnd());
PlanningVehicle planningVehicle = new PlanningVehicle();
planningVehicle.setId(vehicle.getId());
planningVehicle.setCapacity(vehicle.getCapacity());
// each vehicle has its deposit
planningVehicle.setDepot(timeWindowedDepot);
planningVehicles.add(planningVehicle);
});
visits.forEach(visit -> {
//submit to planner location of the visit, add to matrix for calculating distance
PlanningLocation planningLocation = optimizer.submitToPlanner(visit.getLocation());
TimeWindowedVisit timeWindowedVisit = new TimeWindowedVisit();
TimeWindowedVisit timeWindowedVisit = new TimeWindowedVisit(visit.getId(),
planningLocation, visit.getLoad(),visit.getStart(), visit.getEnd(),
visit.getServiceDuration());
planningVisits.add(timeWindowedVisit);
});
//create TWVRP
TimeWindowedVehicleRoutingSolution solution = new TimeWindowedVehicleRoutingSolution();
solution.setId(jobId);
solution.setDepotList(planningDepots);
solution.setVisitList(planningVisits);
solution.setVehicleList(planningVehicles);
return solution;
}
Then I create the solver, start the optimization and finally save the best:
public void solve(UUID jobId) {
if (!planRepository.isResolved(jobId)) {
logger.info("Starting solver");
TimeWindowedVehicleRoutingSolution solution = null;
TimeWindowedVehicleRoutingSolution timeWindowedVehicleRoutingSolution = find(jobId);
try {
SolverJob<TimeWindowedVehicleRoutingSolution, UUID> solverJob =
solverManager.solve(jobId, timeWindowedVehicleRoutingSolution);
solution = solverJob.getFinalBestSolution();
save(jobId, solution);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
} else
logger.info("This job already has a solution");
}
Any help on where the error is will be welcome. I am starting with Optaplanner, please any comments will be very helpful. Thank you very much!
Sorry about the calligraphy, English is not my language.
Thank you very much Geoffrey, I applied your suggestions and found the source of my problem. Grateful for your help!
I will comment on what happened, in case it is useful to someone:
It happens that I was using for the calculation of the distance the example of OptaWeb, that uses GrahHopper for this end and by default it returns the minimum distance, reason why calculation is as far as time. And by introducing time windows, I was breaking the score in:
Math.max(customer.getReadyTime(),
previousDepartureTime + customer.distanceFromPreviousStandstill())
My score was broken because I did not use the same conversion for all variables, the TW: ready time and departure time was expressed in minutes and multiplied by a thousand, while the distance was in milliseconds.
Example:
ready_time: 480000 (8:00 * 60 * 1000)
due_time: 780000 (13:00 * 60 * 1000)
As the distance returned to me:
distance: 641263
And therefore my score was broken.
What I did was to convert all my time variables to milliseconds:
"HH:MM", HH * 3 600 000 and MM * 60 000
Example:
ready_time: 28 800 000
due_time: 46 800 000
service_duration: 60 000 (10min per visit)
Now ready! The arrival time of each vehicle to your visits is adjusted to the defined time windows.

Java 8 Stream API - convert for loop over map & list iterator inside it

In the below code, I am trying to calculate the total price of a basket, where basket is a HashMap containing the products as key and the quantity as value. Promotions are available as a list of Promotion.
I am looping over every map entry and for each of them iterating the promotions. If the promotion matches, I am taking the promotion price (promotion.computeDiscountedPrice()) and removing the promotion from the list (Because a promotion is applicable only to a product & product is unique in the list)
If there is no promotion, we execute block.
if (!offerApplied) { /* .... */ }
Can you please help me in doing this same operation using JAVA 8 stream api?
BigDecimal basketPrice = new BigDecimal("0.0");
Map<String, Integer> basket = buildBasket(input);
List<Promotion> promotions = getOffersApplicable(basket);
for (Map.Entry<String, Integer> entry : trolley.entrySet()) {
boolean offerApplied = false;
Iterator<Promotion> promotionIterator = promotions.iterator();
while (promotionIterator.hasNext()) {
Promotion promotion = promotionIterator.next();
if (entry.getKey().equalsIgnoreCase(offer.getProduct().getProductName())) {
basketPrice = basketPrice.add(promotion.computeDiscountedPrice());
offerApplied = true;
promotionIterator.remove();
break;
}
if (!offerApplied) {
basketPrice = basketPrice.add(Product.valueOf(entry.getKey()).getPrice()
.multiply(new BigDecimal(entry.getValue())));
}
}
return basketPrice;
The simplest and cleaner solution, with a better performance than having to iterate the entire promotions list, is to start by creating a map of promotions identified by the product id (in lower case or upper case [assuming no case collision occurs by the use of equalsIgnoreCase(..)]).
Map<String, Promotion> promotionByProduct = promotions.stream()
.collect(Collectors.toMap(prom -> prom.getProduct()
.getProductName().toLowerCase(), Function.identity()));
This will avoid the need to iterate over the entire array when searching for promotions, it also avoids deleting items from it, which in case of being an ArrayList would need to shift to left the remaining elements each time the remove is used.
BigDecimal basketPrice = basket.keySet().stream()
.map(name -> Optional.ofNullable(promotionByProduct.get(name.toLowerCase()))
.map(Promotion::computeDiscountedPrice) // promotion exists
.orElseGet(() -> Product.valueOf(name).getPrice()) // no promotion
.multiply(BigDecimal.valueOf(basket.get(name))))
.reduce(BigDecimal.ZERO, BigDecimal::add);
It iterates for each product name in the basket, then checks if a promotion exists, it uses the computeDiscountedPrice method, otherwise it looks the product with Product.valueOf(..) and gets the price, after that it mutiplies this value by the quantity of products in the basket and finally the results are reduced (all values of the basket are added) with the BigDecimal.add() method.
Important thing to note, is that in your code, you don't multiply by the quantity the result of promotion.computeDiscountedPrice() (this code above does), i'm not sure if that is a type in your code, or that's the way it should behave.
If case it is in fact the way it should behave (you don't want to multiply quantity by promotion.computeDiscountedPrice()) the code would be:
BigDecimal basketPrice = basket.keySet().stream()
.map(name -> Optional.ofNullable(promotionByProduct.get(name.toLowerCase()))
.map(Promotion::computeDiscountedPrice)
.orElseGet(() -> Product.valueOf(name).getPrice()
.multiply(BigDecimal.valueOf(basket.get(name)))))
.reduce(BigDecimal.ZERO, BigDecimal::add);
Here the only value multiplied by quantity would be the product price obtained with Product.valueOf(name).getPrice().
Finally another option, all in one line and not using the map (iterating over the promotions) using the first approach (multipling by quantity in the end):
BigDecimal basketPrice = basket.keySet().stream()
.map(name -> promotions.stream()
.filter(prom -> name.equalsIgnoreCase(prom.getProduct().getProductName()))
.findFirst().map(Promotion::computeDiscountedPrice) // promotion exists
.orElseGet(() -> Product.valueOf(name).getPrice()) // no promotion
.multiply(BigDecimal.valueOf(basket.get(name))))
.reduce(BigDecimal.ZERO, BigDecimal::add);

Cart discount on Virto Commerce Marketing Module

I would like to do a promotion in Virto Commerce on the cart. In my example i would like to discount the cart with 200 SEK if the customer buys for at least 800 SEK, the VAT/GST in my example is 25%.
This is the effect I'm looking for:
Cart
subTotal: 640
subTotalWithTax: 800
discountAmount: 160
discountTotalWithTax: 200
total: 480
totalWithTax: 600
As far as i can tell the Marketing Module only supports promotions where the discount is applied before taxes. Se comment in storefront code:
ShoppingCart.cs#L390
foreach (var reward in cartRewards)
{
//When a discount is applied to the cart subtotal, the tax calculation has already been applied, and is reflected in the tax subtotal.
//Therefore, a discount applying to the cart subtotal will occur after tax.
//For instance, if the cart subtotal is $100, and $15 is the tax subtotal, a cart - wide discount of 10 % will yield a total of $105($100 subtotal – $10 discount + $15 tax on the original $100).
if (reward.IsValid)
{
var discount = reward.ToDiscountModel(ExtendedPriceTotal);
Discounts.Add(discount);
DiscountAmount = discount.Amount;
}
}
I guess this is a common practice in some markets. But as this is for a B2C solution in Sweden. An advertised discount of 200 SEK on a 800 SEK cart should render a customer facing total price of 600 SEK including taxes.
This is an img of my promotion in the Marketing Module
This gives me the following on the Cart JSON
Cart
subTotal: 640
subTotalWithTax: 800
discountAmount: 160
discountTotal: 160
discountTotalWithTax: 160
subTotalDiscount: 0
subTotalDiscountWithTax:0
discountTotalWithTax: 160
taxTotal: 160
total: 640
totalWithTax: 800 (Calculated. Not in standard JSON response)
So either I've miss configured the promotion or my implementation of the storefront code for promotions is lacking in some way.
Currently, VC implement only the one discount to the order subtotal policy:
When a discount is applied to the cart subtotal, the tax calculation
has already been applied, and is reflected in the tax subtotal.
Therefore, a discount applying to the cart subtotal will occur after
tax. For instance, if the cart subtotal is $100, and $15 is the tax
subtotal, a cart-wide discount of 10% will yield a total of $105 ($100
subtotal – $10 discount + $15 tax on the original $100).
But we are working on change the totals calculation to make this process more flexible and extensible for supporting any calculation policies.
You can achieve what you want by a little customization within your extension module:
Extend ShopingCart class with following code
public class ShopingCart2: ShoppingCart
{
public decimal DiscountAmountWithTax
{
get
{
return DiscountAmount + DiscountAmount * TaxPercentRate;
}
}
public override decimal TaxTotal
{
get
{
var result = base.TaxTotal;
result -= DiscountAmountWithTax - DiscountAmount;
return result;
}
}
public override decimal DiscountTotalWithTax
{
get
{
var result = base.DiscountTotalWithTax;
result += DiscountAmountWithTax - DiscountAmount;
return result;
}
}
}
Extend domain CustomerOrder type with the same code as for ShoppingCart above
Register your ShoopingCart2 and CustomerOrder2 in AbstractTypeFactory
AbstractTypeFactory<ShoppingCart>.OverrideType<ShoppingCart, ShoppingCart2>();
AbstractTypeFactory<CustomerOrder>.OverrideType<CustomerOrder, CustomerOrder2>();
Update your storefront to latest version from dev (this commit required for normal work https://github.com/VirtoCommerce/vc-storefront/commit/2464548c171c811a9d63edba0bdf6af93e8c902b)
Modify ShopingCart class in your storefront - add same changes as you made in your new ShoppingCart2 type earlier.
Get the desired behavior

Odoo v10 display amount in company currency in purchase tree and form view

I am using Odoo v10 .
As we know in purchase.order, there is a base (Monetary) field amount_total which contains value of total amount of a Purchase Order based on (self) currency_id .
Now, I create a new float field home_currency_amount_total in purchase.order .
home_currency_amount_total = fields.Float(string='Total Amount in company currency', store=True)
How can i have a value in this field based on company currency? i.e. I want to have a corresponding value in company base currency and can be used in my tree & form views.
I am new to Odoo and I wonder if there is a "shortcut" (e.g. a built-in compute method) instead of I have to write up related codes.
There is a built-in method for conversion of currency.
Eg.
#api.model
def _compute(self, from_currency, to_currency, from_amount, round=True):
if (to_currency == from_currency):
amount = to_currency.round(from_amount) if round else from_amount
else:
rate = self._get_conversion_rate(from_currency, to_currency)
amount = to_currency.round(from_amount * rate) if round else from_amount * rate
return amount
So, if you want to calculate the conversion you can use this method.
This method takes 3 arguments, first from currency, second to currency and amount which you want to convert as a third argument.
Eg.
self.env['res.currency']._compute(order.currency_id,order.company_id.currency_id,order.amount_total)
Update :
Create you field like this.
home_currency_amount_total = fields.Float(string='Total Amount in company currency', compute="_compute", store=True)
#api.depends('order_lines.price_subtotal','company_id','currency_id')
def _compute(self);
for order in self:
home_currency_amount_total = self.env['res.currency']._compute(order.currency_id,order.company_id.currency_id,order.amount_total)
You can do it using following method.
class PurchaseOrder(models.Model):
_inherit = "purchase.order"
#api.multi
#api.depends('amount_total')
def get_amount_in_company_currency(self):
for purchase_order in self:
if purchase_order.currency_id.id!=purchase_order.company_id.currency_id.id:
currency_id = purchase_order.currency_id.with_context(date=purchase_order.date_order)
purchase_order.home_currency_amount_total = currency_id.compute(purchase_order.amount_total, purchase_order.company_id.currency_id)
else:
purchase_order.home_currency_amount_total=purchase_order.amount_total
home_currency_amount_total = fields.Float(string='Total Amount in company currency',compute="get_amount_in_company_currency",store=True)
In above code we have create one compute field store True, it means value will be store in the database.
When amount_total will change at that time system will calculate home currency amount.
In method we have checked if company currency & purchase order currency is different then system will compute currency amount.
In odoo base module on method is available for compute currency, in which you can pass date in the context.
purchase_order.currency_id.with_context(date=purchase_order.date_order)
Based on context date system will take currency rate, if you not pass
any date then system will take current date rate.
This will help you.

How to use the Shopify API to change the payment status of orders?

I'm building an iOS app for my own Shopify store. I created a private app and using the API key and password to call APIs with the format:
https://apikey:password#hostname/admin/resource.json
Problem occurs when I try to use the API to make the payment status change for orders. (I can create a new order without problem). I don't find any API for changing the financial status of an order. I cannot change the financial status by modifying an order or I even cannot make any transaction by API no matter the "kind" of transactions is: "authorisation", "capture" or "sale".
So how can I change the financial status of an order using the API?
Here is an example for the request and response of using the API:
Object Called:
/admin/orders/#{order_id}/transactions.json
request:
{
"transaction": {
"amount": 50,
"test":true,
"kind": "sale"
}
}
response:
{"errors":{"kind":["sale is not a valid transaction"]}}
Just a couple of things to try:
I noticed in the Transaction doco there are quotes around the amount, which you don't have in your code (e.g. try "50.00" instead of 50):
POST /admin/orders/#{id}/transactions.json
{
"transaction": {
"amount": "10.00",
"kind": "capture"
}
}
Also, have you seen this discussion on the Shopify forums?
...it seems to work so long as the amount of the transaction doesn't exceed the total outstanding balance of the order. From what I have gathered you can not charge or create a transaction for more than the initial sale amount of the order...
You cannot create a transaction or modify the financial_status of any order created via the Shopify API. Refer http://docs.shopify.com/api/order which explicitly says this.
So essentially, you need to pass the financial_status as 'paid' when creating the order and in case your payment was not successful from the gateway, DELETE the order. http://docs.shopify.com/api/order.html#destroy
I got some problem with changing the status of the order earlier , later i solved, to get rid of error you should take care of the following things.
Price of the order should be equal or less than the exact price of the order
Price < exact order price, order will be labeled as Partial Paid
Price = to the exact order price , order will be labbeled as Paid
Paid Price > exact order price , you will get error
Order with status paid, you will get error to change the status of
payment
POST /admin/orders/#{id}/transactions.json
{
"transaction": {
"amount": "10.00",
"kind": "capture"
}
}
$order_get = $shopify('GET', '/admin/orders/'.$order_id.'.json' );
$total_price = $order_get['total_price'];
if( $order_get['financial_status'] != 'paid' ){
$arguments = array( "order" => array(
'note' => 'Paid'
)
);
$order_put = $shopify('PUT', '/admin/orders/'.$order_id.'.json', $arguments);
$arg = array( "transaction" => array(
"amount" => $total_price,
"kind" => "capture"
)
);
$order_put = $shopify('POST', '/admin/orders/'.$order_id.'/transactions.json', $arg);
}
You're not able to write to the financial_status field to mark an order as paid. The financial_status is a result of the transactions that have taken place on an order. So if an order financial_status is currently authorized, you can mark the order as paid by capturing any funds still owing via our Transaction API - or by marking the order as paid within the admin.