Skip to content

Laravel in Amsterdam

Laravel development for Amsterdam companies

A Laravel development company working with Amsterdam teams. Six hours of overlap, English as the working language by default, and a payment method with no card semantics at all.

Amsterdam is two hours behind us, so our afternoon sits inside your working day - about six usable hours, with no scheduling gymnastics.

The second is an advantage that nobody puts in a brief. Engineering here is conducted in English already, so the documentation we write is the documentation your team would have written. Nobody is restating a schema decision in a second language before it can be argued with, and arguing with schema decisions early is most of what makes them survive.

The Amsterdam payment method has no card semantics

This is the local specific that reaches the order model, and it catches teams whose state machine was built for cards.

A card payment has two steps that most order models are built around: authorise at checkout, capture at dispatch. That pattern is why orders have a reserved state, why a capture can be for less than the authorisation, and why an expiring authorisation is a scheduled job.

The dominant method here has none of that. It is a bank transfer: the money moves or it does not. There is nothing to capture later, nothing to partially capture, and a refund is a separate outgoing transfer rather than a reversal of the original.

So an order model designed for cards carries states that cannot occur and lacks ones that do. The states that matter here are different: initiated and awaiting the customer's bank, completed, failed, expired because they never finished. And because the customer leaves your application to complete it, the return is a separate concern from the confirmation - the browser comes back with no state, and what makes the order paid is the notification rather than the redirect.

Subscriptions change too. Recurring collection needs a mandate established as its own step rather than a card stored on file, and that mandate has a lifecycle of its own - the customer can revoke it at their bank without telling you, and the first you hear of it is a collection that failed.

For Amsterdam clients, Laravel invoicing is a network rather than a format

The second specific. Business invoicing here increasingly runs over a network with participants and addressing rather than as a file you generate and email.

That means the application has to know the recipient's address on that network, submit through an access point, and reconcile an acknowledgement that arrives separately from the submission. The invoice becomes an asynchronous document with states - built, sent, acknowledged, rejected - rather than a PDF attached to a message.

The engineering shape is the same as any system-of-record integration: a queue with retries that are safe to repeat, a provider reference stored on the row, and somewhere for a rejection to go that a person actually looks at.

An Amsterdam refund is a transfer, not a reversal

With a card, a refund reverses a capture and the money finds its way back on its own. With a bank-based payment method there is nothing to reverse - the money arrived, and sending it back is a new payment in the other direction.

That changes what the application has to hold. A refund needs a destination account, and the payment that came in may or may not have told you one. If it did, it is worth capturing at the time, because asking the customer for their IBAN weeks later in order to return their own money is a poor conversation and a phishing risk they are right to be suspicious of.

It also changes the states. An outgoing transfer can be initiated, pending, executed or returned, and a refund is not complete when the application decides to issue it. A customer service screen that says "refunded" the moment somebody clicks is wrong for two days and generates the call it was meant to prevent.

Partial refunds and multiple partial refunds against one payment need the arithmetic to be held centrally rather than computed by whoever is looking. Total refunded against a payment, with a constraint that it cannot exceed what was received, prevents the most expensive mistake in this area - which is a refund issued twice because two people were looking at the same order.

Laravel subscriptions when the first Amsterdam payment sets up the mandate

Recurring billing in the Netherlands commonly runs on direct debit, and the mandate for it is frequently obtained through a single bank-based payment that exists mainly to authenticate the customer and capture their account details.

That first payment is therefore doing two jobs, and the subscription is not active until both have succeeded. A customer who abandons at the bank has a subscription record in the application and no mandate behind it, and the cleanest way to handle that is for the subscription to be pending until the mandate exists rather than created optimistically and reconciled later.

Pre-notification is an obligation rather than a courtesy. The customer is told the amount and the date in advance of each collection, with a defined notice period, and that notification is part of the billing run instead of a marketing email somebody might switch off. Storing the notification against the collection, with its date, is what lets the business answer a dispute.

The dispute window is long - substantially longer than a card chargeback - and the money can come back for weeks after it arrived. Which means revenue recognised on collection is provisional for that period, and a subscription whose collection is reversed has to handle the reversal without immediately cancelling an account that may simply have had a bank problem. A dunning sequence with defined retries, notifications and a final suspension date is the part worth specifying before launch rather than after the first month's failures.

Commercially

The invoice comes from Codefacture Yazılım A.Ş., registered in Türkiye, in euros by bank transfer, with no Turkish VAT under the export-of-services exemption. Scope is fixed in writing before work starts and priced per project.

Everything that applies nationwide - the invoicing network itself, how the regulator reads consent - is set out on the Netherlands market page.

The regulatory and commercial ground for this city is on the Netherlands market page.

Frequently asked questions

Why does the payment method change the order model?
There is no authorisation and capture. A card lets you reserve funds and take them later, which is how most order state machines are built - reserve on checkout, capture on dispatch. Here the money moves or it does not, and refunds are separate transfers rather than reversals. An order model built around reserving and capturing has states that cannot occur and lacks ones that do.
What is different about invoicing over a network?
It is a network with participants and addressing, not a file format you generate. Your application has to know the recipient's address on that network, submit through an access point, and handle an acknowledgement that arrives separately. The invoice becomes an asynchronous document with states rather than a PDF you attach to an email.
Do subscriptions work differently?
Yes. Recurring collection needs a mandate set up as its own step rather than a stored card, so the signup flow has an extra stage and the mandate has its own lifecycle - it can be revoked by the customer at their bank without telling you first, and the first you learn of it is a failed collection.
Our Amsterdam office runs in Dutch. Is working in English genuinely fine?
It is, and the reason is worth naming. Engineering in the Netherlands is conducted in English as a matter of course, so a pull request description, a migration plan and an incident write-up all arrive in the language they were thought in. Nothing is being translated on the way to the reviewer, which is where most of the cost of a second language actually sits.
Call us+1 848 272 7583WhatsApp+90 850 308 5436Emailinfo@codefacture.comContact page