# Payment Links

A Payment Link is a PayMongo-hosted payment page for one amount, at a URL you share wherever you talk to the customer: chat, email, social media, or an invoice. The customer pays with any method your account accepts, and gets an email receipt. There is no checkout on your site and no redirect back to it.

Every method lives on `Paymongo::paymentLinks()`, and a single link comes back as a [`PaymentLink`](/data-objects.md#paymentlink). For every attribute PayMongo accepts, see its [Payment Links reference](https://docs.paymongo.com/reference/payment-links).

Payment Links are PayMongo's successor to [Classic Links](/links.md). Use them for new integrations.

## Create a link

`create()` takes the link's attributes. Send the customer the `url` it returns:

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

$link = Paymongo::paymentLinks()->create([
    'amount' => 150050, // PHP 1,500.50, in centavos
    'currency' => 'PHP',
    'description' => 'Invoice INV-1234',
    'remarks' => 'Custom order via Messenger', // for you; customers do not see it
    'metadata' => ['invoice_id' => '1234'],
    'restriction' => ['completed_sessions' => ['limit' => 1]], // stop after one payment
], idempotencyKey: 'invoice-1234-link');

$link->url;             // "https://pm.link/...", send this to your customer
$link->referenceNumber; // the short reference at the end of the URL
```

- `amount` is integer centavos, at least `100` (PHP 1.00). `currency` and `description` are required too.
- `restriction.completed_sessions.limit` is how many times the link can be paid, from 0 to 100. PayMongo defaults it to 1.
- `remarks` and `metadata` are for you. The customer sees the `description`.
- `idempotencyKey:` makes a retried request return the same link instead of creating a second one.

## Retrieve and update a link

`retrieve()` returns the link. `update()` changes its `amount`, `description`, or `remarks`:

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

$link = Paymongo::paymentLinks()->retrieve('plink_uSJXoxTBNqRrg35kj5w9dTVY');

$link->status;    // ?PaymentLinkStatus: Active or Archived
$link->createdAt; // ?CarbonImmutable

$link = Paymongo::paymentLinks()->update('plink_uSJXoxTBNqRrg35kj5w9dTVY', [
    'description' => 'Invoice INV-1234 (revised)',
    'amount' => 175000,
]);
```

A link's `status` is whether it takes payments (`Active`) or not (`Archived`), not whether it was paid. To see what was paid, list its payments.

## Archive and unarchive a link

`archive()` stops a link from taking payments, and `unarchive()` opens it again:

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

$link = Paymongo::paymentLinks()->archive('plink_uSJXoxTBNqRrg35kj5w9dTVY');   // stops taking payments
$link = Paymongo::paymentLinks()->unarchive('plink_uSJXoxTBNqRrg35kj5w9dTVY'); // takes them again
```

## List links

`list()` returns a page of links. Pass `status`, `reference_number`, or `mode` (`live` or `test`) to filter them:

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

foreach (Paymongo::paymentLinks()->list(['status' => 'active']) as $link) {
    $link->description;
    $link->url;
}
```

The page is a `Luigel\Paymongo\Pagination\CursorPage`. Iterate it for its links, check `hasMore`, and call `nextPage()` for the next one, or `lazy()` to walk every page.

## See what a link was paid

`payments()` returns a page of the [payments](/data-objects.md#payment) made through a link:

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

$payments = Paymongo::paymentLinks()->payments('plink_uSJXoxTBNqRrg35kj5w9dTVY');

foreach ($payments as $payment) {
    if ($payment->status === PaymentStatus::Paid) {
        $payment->money()?->format(); // "₱1,500.50"
    }
}
```

## Refund a link's payment

Refund a payment made through a link as you would any other payment, with `Paymongo::refunds()`, which returns a typed `Refund`:

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

$refund = Paymongo::refunds()->create([
    'payment_id' => 'pay_i7tdqnmwdszWo5B4Xqk2ogX5', // a payment from payments() above
    'amount' => 150050, // centavos, like every other amount
    'reason' => RefundReason::Others,
]);
```

`paymentLinks()->refund()` calls PayMongo's refund endpoint for payment links instead, and also returns a `Refund`. It takes a flat body of `payment_id`, `amount`, `reason`, and `metadata`, and PayMongo documents its `amount` in pesos rather than centavos, unlike every other amount (the `Refund` it returns is in centavos), so prefer `refunds()`:

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

$refund = Paymongo::paymentLinks()->refund('plink_uSJXoxTBNqRrg35kj5w9dTVY', [
    'payment_id' => 'pay_i7tdqnmwdszWo5B4Xqk2ogX5',
    'amount' => 1500.50, // pesos here, unlike every other amount
    'reason' => 'requested_by_customer',
]);

$refund->amount; // 150050, back in centavos
```

## Know when it was paid

PayMongo sends `link.payment.paid` when a customer pays a link, and the package dispatches it as `Luigel\Paymongo\Events\LinkPaymentPaid`. See [Webhooks](/webhooks.md).
