Customer: First and Last Name #787
Replies: 3 comments 10 replies
-
Technically, Simple Commerce should support separate first & last name fields. See the However, admittedly, it's not a feature I do a lot of testing around so there could be spots where support for it is missed. Do you have any specific examples of any places you're running into issues with using separate fields? |
Beta Was this translation helpful? Give feedback.
-
Also, yes, would love for you to share your Mollie Orders implementation. I worked on refactoring the 1st party integration ages ago to it but never got around to finishing it (see #363). I only just deleted the branch for it a few days ago. |
Beta Was this translation helpful? Give feedback.
-
Here's my code for using Mollie gateway with orders. It works, though it's not pretty. The only issue is shipping is a line-item in the order (and oddly can be marked as shipped) but I couldn't find another way to add the shipping costs and Mollie support doesn't like to reply 🤷 The main changes to the Mollie gateway to get it working with orders are in the Prepare Methodpublic function prepare(Prepare $data): Response
{
$this->setupMollie();
$mollieOrder = $this->buildOrder($data->order());
$order = $this->mollie->orders->create($mollieOrder, ['embed' => 'payments']);
return new Response(true, [
'id' => $order->id,
], $order->getCheckoutUrl());
} Webhook Methodpublic function webhook(Request $request)
{
$this->setupMollie();
$mollieOrder = $this->mollie->orders->get($request->get('id'));
$order = OrderFacade::find($mollieOrder->metadata->order_id);
if (!$order) {
throw new OrderNotFound("Order related to Mollie transaction [{$mollieOrder->id}] could not be found.");
}
// Only mark as paid if not already paid (sends notifications, etc.)
if ($mollieOrder->isPaid() && $order->isPaid() !== true) {
$this->markOrderAsPaid($order);
} elseif ($mollieOrder->isCompleted() && $order->isShipped() !== true) {
$order->markAsShipped();
}
} buldOrder Method/**
* Build new Mollie order
*
* @see https://docs.mollie.com/reference/v2/orders-api/create-order
*/
protected function buildOrder(Order $order): array
{
$mollieOrder = [
'redirectUrl' => $this->callbackUrl([
'_order_id' => $order->id(),
]),
'webhookUrl' => $this->webhookUrl(),
'locale' => 'de_DE',
'metadata' => [
'order_id' => $order->id,
'description' => $order->get('title'),
],
];
$mollieOrder['orderNumber'] = (string) $order->orderNumber();
$mollieOrder['amount'] = [
'currency' => Currency::get(Site::current())['code'],
'value' => (string) substr_replace($order->grandTotal(), '.', -2, 0),
];
// Each line contains details such as a description of the item ordered, its price etc.
foreach($order->lineItems() as $item) {
$mollieOrder['lines'][] = [
'type' => 'physical',
'name' => $item->product->data['title'],
'quantity' => $item->quantity,
// The price of a single item including VAT in the order line.
'unitPrice' => [
'currency' => Currency::get(Site::current())['code'],
'value' => (string) number_format($item->product->price / 100, 2),
],
// The VAT rate applied to the order line
'vatRate' => (string) $item->tax['rate'],
// The amount of value-added tax on the line.
'vatAmount' => [
'currency' => Currency::get(Site::current())['code'],
'value' => (string) number_format($item->tax['amount'] / 100, 2),
],
// The total amount of the line, including VAT and discounts. (unitPrice × quantity) - discountAmount
'totalAmount' => [
'currency' => Currency::get(Site::current())['code'],
'value' => (string) number_format(($item->product->price * $item->quantity) / 100, 2),
],
'sku' => $item->product->data['sku'],
'imageUrl' => $item->product->data['gallery'][0] ? asset('assets/' . $item->product->data['gallery'][0]) : '',
'productUrl' => url('products/' . $item->product->data['slug']),
'metadata' => json_encode([]),
];
}
$shippingMethod = collect(SimpleCommerce::shippingMethods())->firstWhere('class', $order->data->get('shipping_method'));
if ($shippingMethod) {
// Shipping costs as line item.
$mollieOrder['lines'][] = [
'type' => 'shipping_fee',
'name' => $shippingMethod['name'],
'quantity' => 1,
'unitPrice' => [
'currency' => Currency::get(Site::current())['code'],
'value' => (string) number_format($order->shippingTotal / 100, 2),
],
'vatRate' => '0.00',
'vatAmount' => [
'currency' => Currency::get(Site::current())['code'],
'value' => (string) '0.00',
],
'totalAmount' => [
'currency' => Currency::get(Site::current())['code'],
'value' => (string) number_format($order->shippingTotal / 100, 2),
],
];
}
if (
!$order->shippingAddress()
|| $order->shippingAddress()?->name() === null
|| empty($order->shippingAddress()->name())
){
Log::error("Missing shipping information!", [
'order_title' => $order->get('title'),
'order_id' => $order->id,
'address' => $order->shippingAddress(),
]);
}
// Mollie requires a first and last name. This is a terrible solution to this.
$fullName = $order->shippingAddress()->name();
$firstName = substr($fullName, 0, strpos($fullName, ' '));
$lastName = trim(substr($fullName, strlen($firstName)));
// Mollie needs the billing address only, shipping is optional.
if ($order->billingAddress()) {
$fullNameBilling = $order->billingAddress()?->name() ?? '';
$firstNameBilling = substr($fullNameBilling, 0, strpos($fullNameBilling, ' '));
$lastNameBilling = trim(substr($fullNameBilling, strlen($firstNameBilling)));
$mollieOrder['billingAddress'] = [
'givenName' => $firstNameBilling,
'familyName' => $lastNameBilling,
'email' => $order->customer->email,
'streetAndNumber' => $order->billingAddress()->addressLine1(),
'streetAdditional' => $order->billingAddress()->addressLine2(),
'postalCode' => $order->billingAddress()->zipCode(),
'city' => $order->billingAddress()->city(),
'country' => $order->billingAddress()->country()['iso'],
];
$mollieOrder['shippingAddress'] = [
'givenName' => $firstName,
'familyName' => $lastName,
'email' => $order->customer->email,
'streetAndNumber' => $order->shippingAddress()->addressLine1(),
'streetAdditional' => $order->shippingAddress()->addressLine2(),
'postalCode' => $order->shippingAddress()->zipCode(),
'city' => $order->shippingAddress()->city(),
'country' => $order->shippingAddress()->country()['iso'],
];
} else {
$mollieOrder['billingAddress'] = [
'givenName' => $firstName,
'familyName' => $lastName,
'email' => $order->customer->email,
'streetAndNumber' => $order->shippingAddress()->addressLine1(),
'streetAdditional' => $order->shippingAddress()->addressLine2(),
'postalCode' => $order->shippingAddress()->zipCode(),
'city' => $order->shippingAddress()->city(),
'country' => $order->shippingAddress()->country()['iso'],
];
}
return $mollieOrder;
} |
Beta Was this translation helpful? Give feedback.
-
I'm currently working on a custom Mollie gateway that uses their Orders API instead of only payments. An order in Mollie requires billing and (optionally) shipping information. The issue is the first and last name must be given as two separate properties in the API.
I'm looking into exactly what I would need to update in order to support this in Simple Commerce, but it's starting to look like it would touch quite a few classes. So I'm putting it out there to see if anyone has a solid solution for this, or if it would potentially be something implemented directly into Simple Commerce.
Additionally I'd be happy to share my Mollie orders implementation if anyone would be interested 🤷♂️
Beta Was this translation helpful? Give feedback.
All reactions