# Customers

A Customer is a person you charge more than once. It holds their contact details and the payment methods saved against them, so a returning customer can pay with a saved card, and a [subscription](/subscriptions.md) can charge them every cycle.

Every method lives on `Paymongo::customers()`, and a single customer comes back as a [`Customer`](/data-objects.md#customer). For every attribute PayMongo accepts, see its [Customers reference](https://docs.paymongo.com/reference/create_customers).

## Create a customer

`create()` takes the customer's details. Create one per user and store its id on your user:

```php
use Luigel\Paymongo\Enums\DefaultDevice;
use Luigel\Paymongo\Facades\Paymongo;

$customer = Paymongo::customers()->create([
    'first_name' => 'Juan',
    'last_name' => 'dela Cruz',
    'email' => 'juan@example.com',        // unique per customer
    'phone' => '+639171234567',           // unique per customer
    'default_device' => DefaultDevice::Email, // or DefaultDevice::Phone
]);

$customer->id; // "cus_...", store it on your user
```

- `first_name`, `last_name`, `email`, and `default_device` are required. `default_device` is a `Luigel\Paymongo\Enums\DefaultDevice` case (`Phone` or `Email`) or its value.
- `email` and `phone` must be unique to one customer on your account.
- A customer belongs to your PayMongo account. Its saved cards cannot be used on another account.

## Retrieve and update a customer

`retrieve()` returns the customer. `update()` changes only the keys you pass:

```php
use Luigel\Paymongo\Facades\Paymongo;

$customer = Paymongo::customers()->retrieve('cus_b9ENKVqcHBfQQmv26uDYDCsD');

$customer->email;
$customer->defaultDevice;          // ?DefaultDevice: Phone or Email
$customer->defaultPaymentMethodId; // "pm_..." once a card is vaulted

$customer = Paymongo::customers()->update('cus_b9ENKVqcHBfQQmv26uDYDCsD', [
    'email' => 'juan.delacruz@example.com', // only the keys you pass change
]);
```

## Delete a customer

`delete()` deletes the customer and returns `true`. When PayMongo refuses, it throws a `Luigel\Paymongo\Exceptions\PaymongoException` instead:

```php
use Luigel\Paymongo\Facades\Paymongo;

Paymongo::customers()->delete('cus_b9ENKVqcHBfQQmv26uDYDCsD'); // true, or throws
```

## Save and reuse a card

PayMongo saves a card to a customer when the customer pays a [payment intent](/payment-intents.md) created with `setup_future_usage` naming them:

```php
use Luigel\Paymongo\Facades\Paymongo;

$intent = Paymongo::paymentIntents()->create([
    'amount' => 150050,
    'currency' => 'PHP',
    'payment_method_allowed' => ['card'],
    'setup_future_usage' => [
        'session_type' => 'on_session', // the customer is there to pay again
        'customer_id' => 'cus_b9ENKVqcHBfQQmv26uDYDCsD',
    ],
]);

// Take the payment as usual. Once it succeeds, the card is saved to the customer.
```

Card saving (PayMongo calls it card vaulting) takes Visa and Mastercard only, and PayMongo must enable it on your account first. See PayMongo's [Card vaulting](https://docs.paymongo.com/docs/payment-acceptance-card-vaulting) guide.

`paymentMethods()` lists what is saved, as [`CustomerPaymentMethod`](/data-objects.md#customerpaymentmethod)s, and `deletePaymentMethod()` removes one:

```php
use Luigel\Paymongo\Facades\Paymongo;

$saved = Paymongo::customers()->paymentMethods('cus_b9ENKVqcHBfQQmv26uDYDCsD');

foreach ($saved as $method) {
    $method->paymentMethodId;         // "pm_...", attach this to a payment intent
    $method->paymentMethodType;       // "card", ...
    $method->sessionType;             // "on_session", ...
    $method->details['last4'] ?? null; // for your "Pay with card ending 4242" button
}

// Forget one, e.g. when the customer removes it from their account:
Paymongo::customers()->deletePaymentMethod('cus_b9ENKVqcHBfQQmv26uDYDCsD', 'pm_wr98R2gwWroVxfkcNVZBuXg2');
```

To charge a saved card, [attach](/payment-intents.md#attach-a-payment-method) its `paymentMethodId` to a new payment intent. PayMongo first wants the card's CVC again, set by updating the payment method, which the package does not wrap yet. See the Card vaulting guide for that request.
