# B2bFatturazione Documentation

Installation steps and everything you need to expose the B2B fields through your own storefront, including GraphQL/headless checkouts like React Checkout.

## Installation

### Requirements

Magento 2.4.x — tested on 2.4.9, compatible with previous 2.4.* releases. PHP 8.1–8.5. Compatible with both the default Luma theme and the Hyvä theme.

### Setup steps

1. Add the credentials you'll receive by email to `auth.json` in your Magento project root:
   ```json
   { "http-basic": { "repo.codingrow.com": { "username": "...", "password": "..." } } }
   ```
2. `composer config repositories.codingrow composer https://repo.codingrow.com`
3. `composer require codingrow/module-b2bfatturazione`
4. `bin/magento module:enable Codingrow_B2bFatturazione`
5. `bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush`
6. Paste your license key into **Admin → Stores → Configuration → Codingrow Extensions → B2bFatturazione → License → License Key**, save, then `bin/magento cache:flush`. The key is bound to the domain declared at purchase — on any other domain the module stays installed but its fields stay disabled.
7. If the site runs in `production` mode, also redeploy static content: `bin/magento setup:static-content:deploy -f`.

### Uninstallation

`composer remove codingrow/module-b2bfatturazione` then `bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush`.

## What it does

This is a deliberately small, focused module: it adds five fields — **Customer Type** (business/private), **VAT number**, **SDI code**, **PEC** (certified email), and **Fiscal Code** — to the customer address book and to checkout (billing and shipping), on both the default Luma theme and Hyvä. There's no configuration beyond installing it and pasting the license key; it just works once installed.

## GraphQL / headless & React Checkout compatibility

The five B2B fields are exposed through Magento's own **core** GraphQL types and mutations — not a custom API. If your storefront is GraphQL-based (React Checkout, or any other headless/GraphQL frontend), you read and write these fields exactly like any other native address field, through the mutations you're already using.

### Reading the fields

`customer_type`, `sdi`, `pec`, `codice_fiscale` and `fattura_richiesta` are added directly onto Magento's own `BillingCartAddress`, `ShippingCartAddress` and `CustomerAddress` types:

```graphql
{
  customerCart {
    billing_address {
      customer_type
      sdi
      pec
      codice_fiscale
      fattura_richiesta
    }
  }
}
```

```graphql
{
  customer {
    addresses {
      customer_type
      sdi
      pec
      codice_fiscale
      fattura_richiesta
    }
  }
}
```

### Writing the fields

The same five fields are added to Magento's own core `CartAddressInput` type, so they're passed alongside the normal address fields in the standard cart mutations — no separate mutation to call:

```graphql
mutation {
  setShippingAddressesOnCart(
    input: {
      cart_id: "abc123"
      shipping_addresses: [
        {
          address: {
            firstname: "Mario"
            lastname: "Rossi"
            street: ["Via Roma 1"]
            city: "Milano"
            postcode: "20100"
            country_code: "IT"
            telephone: "+390000000"
            customer_type: "azienda"
            sdi: "ABC1234"
            pec: "mario.rossi@pec.it"
            codice_fiscale: "RSSMRA80A01F205X"
          }
        }
      ]
    }
  ) {
    cart { id }
  }
}
```

### Implementation notes

- All of this is done through official Magento extension points (`di.xml` plugins on core interfaces like `Magento\QuoteGraphQl\Model\Cart\QuoteAddressFactory` and `Magento\CustomerGraphQl\Model\Customer\Address\ExtractCustomerAddressData`) — nothing patches or copies core GraphQL resolver code.
- Server-side validation (e.g. "SDI or PEC is required for a business customer") runs the same way regardless of which storefront calls the mutation — REST, GraphQL, or the default Luma checkout.
- `fattura_richiesta` (invoice requested) only applies to private customers — business customers always receive an invoice by law, so the field is meaningful specifically for the "privato" case.

### Accurate address display in admin

The customer's default billing/shipping address summary in **Customers → All Customers → [customer] → Addresses**, and on the **Customer View** tab, now includes the B2B fields too — not just the base address:

```
Before                          After
------                          -----
Mario Rossi                     Mario Rossi
Mario Rossi S.r.l.              Mario Rossi S.r.l.
Via dei Test, 1                 Via dei Test, 1
Roma, RM, 00100                 Roma, RM, 00100
Italy                           Italy
T: 333 1122334                  T: 333 1122334
VAT: 01234567891                Customer Type: azienda
                                 VAT: 01234567891
                                 SDI: ABCDEFG
                                 PEC: mario.rossi@pec.it
                                 Fiscal Code: RSSMRA80A01H501V
```

## React Checkout: ready to use, out of the box

Codingrow also maintains **[codingrow/module-react-checkout](https://github.com/Snafruz/codingrow-react-checkout)**, a small companion package that adds the actual B2B billing form (customer type, VAT, SDI, PEC, fiscal code) to Hyvä's [React Checkout](https://github.com/friends-of-hyva/magento2-react-checkout) — the UI on top of the GraphQL fields documented above. Install both together and the billing form works immediately, no custom development required.

**It also includes our own compatibility patch that makes React Checkout actually run on PHP 8.4 and 8.5.** The upstream package predates PHP 8.4's stricter deprecation handling — implicit nullable parameters and an unescaped `str_getcsv()` call both throw *fatal errors* under Magento's error handler on 8.4+, not just warnings, which otherwise makes React Checkout unusable on a modern PHP stack. This patch is applied automatically as part of the installation below.

### Installing React Checkout with B2B support

1. Require both packages:
   ```bash
   composer require hyva-themes/magento2-react-checkout codingrow/module-react-checkout
   ```
2. Add the PHP 8.4/8.5 compatibility patch to your project's root `composer.json`, then run `composer update --lock` so it's recorded:
   ```json
   "extra": {
       "patches": {
           "hyva-themes/magento2-react-checkout": {
               "PHP 8.4/8.5 compat": "vendor/codingrow/module-react-checkout/patches/react-checkout-php84-compat.patch"
           }
       }
   }
   ```
   (Requires [`cweagans/composer-patches`](https://github.com/cweagans/composer-patches); `composer require cweagans/composer-patches` first if you don't already have it.)
3. Enable the modules:
   ```bash
   bin/magento module:enable Codingrow_ReactCheckout Hyva_ReactCheckout
   bin/magento setup:upgrade
   ```
4. Turn on React Checkout: `bin/magento config:set hyva_react_checkout/general/enable 1`
5. Build the React app:
   ```bash
   cd vendor/codingrow/module-react-checkout/reactapp
   npm install
   npm run build
   ```
6. Redeploy static content — **required every time**, even outside `production` mode; the browser can otherwise keep loading a stale bundle:
   ```bash
   bin/magento setup:static-content:deploy -f en_US --theme <your-theme>
   ```
7. `bin/magento cache:flush`

Requirements: Magento 2.4.9, PHP 8.1–8.5 (including 8.4/8.5, via the included patch).
