APIv4 Order API
Related: Payment API financial#223
Line Items
To add a Line Item we need
- Unit Price + Quantity.
- Tax? What do we do with Tax?
- The ability to specify a link to any other entity (eg. Membership, Participant, Resource etc). This can use the params:
- entity_table="civicrm_participant" or entity="Participant". (entity style to be added later).
- entity_id: The actual ID of the entity.
- entity_id.x: This syntax allows us to create or update(?) the related entity. Accepts all fields that are accepted by the related entity API.
- Optional:
- price_field_value_id: If this is not specified code will be used to automatically identify the default price_field_value_id and use that instead. See sample code in https://lab.civicrm.org/extensions/mjwshared/-/blob/master/Civi/Api4/Action/PriceFieldValue/GetDefaultPriceFieldValueForContributionMJW.php?ref_type=heads and https://lab.civicrm.org/extensions/mjwshared/-/blob/master/Civi/Api4/Action/PriceFieldValue/GetDefaultPriceFieldValueForMembershipMJW.php?ref_type=heads
ModifyLineItem
This allows you to modify a LineItem on a Pending Order. It is not possible once the Order is Completed.
Default
Questions
- What happens with a free/zero amount Order?
- Should we be able to create a Contact during Order Create? Eg. for Contribution but also for multiple Participants etc.
Validate Order
In the first phase we won't have a way to validate Order but we will need to add one.
For example to check if event is (or will be) Full.
@eileen )
Implementation Details (fromThere is general agreement that the biggest issue with the v3 api is the confusing arrays it requires. My preference in fact is for a fairly non-standard Order api - ie
Order::create()
->setContributionParameters([
'contact_id' => 56,
'financial_type_id:name' => 'Donation',
])
->addLineItem([
'price_field_value_id:name' => 'student_rate',
'entity_id.role_id:name' => 'Attended',
'entity_id.contact_id' => 87,
'entity_id.event_id' => 6,
'entity_table' => 'civicrm_participant',
])
->execute();
On update we would have actions like addLineItem
, removeLineItem
Obviously this starts to highlight a whole lot of issues
1) at the contribution params level there are some parameters that we have long-standing discussions around - financial_type_id, receive_date, payment_instrument_id. I think we should probably not start with talking about those as we might never get any further
2) line items
- one specific thing I think we all agree on is that we don't want line items to have to belong to the same price set. There will be some fighting with the code to get there but it's probably an issue that lives outside the bike shed
- in the example above the entity_table is passed in. For memberships that can be inferred from the price_field_value_id, but for event participants there is nothing on the price field or price_field_value that declares something as being event related
- for line items we kinda want to require the minimum required info which varies a bit.... ie
-- if we have only the line_total (in the line item or just the contribution.total_amount) we can assume
- the price field id is the default contribution price field
- the quantity is 1
- the unit_price is the line_total
-- if we have only the qty and the unit_price we can assume
- the price field id is the default contribution price field
- the line_total is unit_price * qty
-- if we have only the line_total and the entity_table, which is civicrm_membership we can assume
- the price field id is the default membership field **but we require one of membership_type_id or price_field_value_id, from which we can determine amounts **
-- if we have only the price_field_value id we can assume
- the amount & price field can be looked up from it. We can assume qty to be 1 unless provided
- We need some way of specifying relevant entity values. (I suspect this is where the rubber hits the brake pads in the bikeshedding process). In the above example I have leveraged
entity_id
in the way we do for other apiv4 related entities. The v3 order api had some ideas about entity parameters which didn't align with our specification that closely - I think they were effectively 'sub-participants' and if we want to add that it might be'entity_id.registered_participants' => []
perhaps. It's also rather tempting to refer to useparticipant_id
to stand in forentity_id
when it reflects the line....
3) the add payment. We currently chain this - I did include above in the first iteration of this but removed based on the discussion. The world won't end if we don't do that.