petzsch/laravel-btcpay

This package is abandoned and no longer maintained. No replacement package was suggested.

BtcPay wrapper for laravel

v6.0.3 2022-11-18 13:04 UTC

README

This project is not maintained anymore. And therefore was archived.

LaravelBtcPay

LaravelBtcPay Social Image

Latest Version on Packagist Total Downloads

LaravelBtcPay enables you and your business to transact in Bitcoin, Litecoin and 10+ other BtcPay-supported cryptocurrencies within your Laravel application.

Requires PHP ^7.3

Supported Resources

Contents

Installation

Install package

You can install the package via composer:

composer require petzsch/laravel-btcpay

Publish config file

Publish config file with:

php artisan vendor:publish --provider="Petzsch\LaravelBtcpay\LaravelBtcpayServiceProvider"

This will create a laravel-btcpay.php file inside your config directory.

Add configuration values

Add the following keys to your .env file and update the values to match your preferences (read more about configuration):

BTCPAY_API_KEY=YourRandomApiKeyThatYouOptainedFromYourBTCPayUserSettings
BTCPAY_SERVER_URL=https://btcpay.your.server.tld

Configure Webhooks (Optional)

BtcPay resource status updates are completely based on webhooks (IPNs). LaravelBtcPay is fully capable of automatically handling webhook requests. Whenever a webhook is received from BtcPay's server, BtcpayWebhookReceived event is dispatched. Take the following steps to configure your application for webhook listening:

1. Setup your webhook route

Resolve the btcPayWebhook route macro in your desired route file (web.php is recommended). The macro accepts a single, optional argument, which is the URI path at which you want to receive BtcPay webhook POST requests. If none is provided, it defaults to 'laravel-btcpay/webhook':

// ... your other 'web' routes

Route::btcPayWebhook(); // https://example.com/laravel-btcpay/webhook

// OR ...

Route::btcPayWebhook('receive/webhooks/here'); // https://example.com/receive/webhooks/here

ℹ️ To retrieve your newly created webhook route anywhere in your application, use: route('laravel-btcpay.webhook.capture')

LaravelBtcPay also offers the convenience of auto-populating your configured webhook url on applicable resources. Specifically when:

You may enable this feature per-resource by uncommenting the respective entry within the auto_populate_webhook array found in the laravel-btcpay.php config file.

⚠️ If a value is manually set, most likely via $resource->setNotificationURL('https://...') during resource initialization, auto-population is overridden.

2. Setup your webhook listener

Start by generating an event listener:

php artisan make:listener BtcPayWebhookListener --event=\Petzsch\LaravelBtcpay\Events\BtcpayWebhookReceived

Then, implement your application-specific logic in the handle(...) function of the generated listener.

In the following example, we assume you have previously created an invoice, storing its token on your internal Order model:

/**
 * Handle the webhook event, keeping in mind that the server doesn't trust the client (us), so neither should
 * we trust the server. Well, trust, but verify.
 *
 * @param BtcpayWebhookReceived $event
 * @return void
 */
public function handle(BtcpayWebhookReceived $event)
{
    // Extract event payload
    $payload = $event->payload;

    // Verify that webhook is for a BtcPay Invoice resource
    if (in_array($payload['event']['code'], array_keys(BtcPayConstants::INVOICE_WEBHOOK_CODES))) {
        try {
            // Do not trust the webhook data. Pull the referenced Invoice from BtcPay's server
            $invoice = LaravelBtcpay::getInvoice($payload['data']['id']);

            // Now grab our internal Order instance for this supposed Invoice
            $order = Order::whereOrderId($invoice->getOrderId())->first();

            // Verify Invoice token, previously stored at time of creation
            // Learn more at: https://github.com/petzsch/laravel-btcpay#create-an-invoice
            if ($invoice->getToken() !== $order->invoice_token) {
                return;
            }

            $invoice_status = $invoice->getStatus();

            // Do something about the new Invoice status
            if ($invoice_status === InvoiceStatus::Paid) {
                $order->update(['status' => $invoice_status]) && OrderStatusChanged::dispatch($order->refresh());
            }
        } catch (BtcPayException $e) {
            Log::error($e);
        }
    }
}

Finally, map your listener to the BtcpayWebhookReceived event inside the $listen array of your EventServiceProvider:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    // ... other event-listener mappings
    BtcpayWebhookReceived::class => [
        BtcPayWebhookListener::class,
    ],
]

Examples

Invoices

Invoices are time-sensitive payment requests addressed to specific buyers. An invoice has a fixed price, typically denominated in fiat currency. It also has an equivalent price in the supported cryptocurrencies, calculated by BtcPay, at a locked exchange rate with an expiration time of 15(or whatever you configured) minutes.

Create an invoice

In this example we assume you've already created an instance of your equivalent Order model, to be associated with this Invoice (referred to as $order):

TODO: Check if all of this works with the invoice object exposed by greenfield!!!

// Create instance of Invoice
$invoice = LaravelBtcpay::Invoice(449.99, 'USD');

// Set item details (Only 1 item per Invoice)
$invoice->setItemDesc('You "Joe Goldberg" Life-Size Wax Figure');
$invoice->setItemCode('sku-1234');
$invoice->setPhysical(true); // Set to false for digital/virtual items

// Ensure you provide a unique OrderId for each Invoice
$invoice->setOrderId($order->order_id);

// Create Buyer Instance
$buyer = LaravelBtcpay::Buyer();
$buyer->setName('John Doe');
$buyer->setEmail('john.doe@example.com');
$buyer->setAddress1('2630 Hegal Place');
$buyer->setAddress2('Apt 42');
$buyer->setLocality('Alexandria');
$buyer->setRegion('VA');
$buyer->setPostalCode(23242);
$buyer->setCountry('US');
$buyer->setNotify(true); // Instructs BtcPay to email Buyer about their Invoice

// Attach Buyer to Invoice
$invoice->setBuyer($buyer);

// Set URL that Buyer will be redirected to after completing the payment, via GET Request
$invoice->setRedirectURL(route('your-btcpay-success-url'));
// Set URL that Buyer will be redirected to after closing the invoice or after the invoice expires, via GET Request
$invoice->setCloseURL(route('your-btcpay-cancel-url'));
$invoice->setAutoRedirect(true);

// Optional. Learn more at: https://github.com/vrajroham/laravel-btcpay#1-setup-your-webhook-route
$invoice->setNotificationUrl('https://example.com/your-custom-webhook-url');

// This is the recommended IPN format that BtcPay advises for all new implementations
$invoice->setExtendedNotifications(true);

// Create invoice on BtcPay's server
$invoice = LaravelBtcpay::createInvoice($invoice);

$invoiceId = $invoice->getId();
$invoiceToken = $invoice->getToken();

// You should save Invoice ID and Token, for your reference
$order->update(['invoice_id' => $invoiceId, 'invoice_token' => $invoiceToken]);

// Redirect user to the Invoice's hosted URL to complete payment
// This could be done more elegantly with our JS modal!
$paymentUrl = $invoice->getUrl();
return Redirect::to($paymentUrl);

ℹ️ It is highly recommended you store the Invoice ID and Token on your internal model(s). The token can come in handy when verifying webhooks.

Retrieve an existing invoice

$invoice = LaravelBtcpay::getInvoice('invoiceId_sGsdVsgheF');

Retrieve a list of existing invoices

In this example we retrieve all MTD (Month-To-Date) invoices: TODO: unsupported by Greenfield!!!

$startDate = date('Y-m-d', strtotime('first day of this month'));
$endDate = date('Y-m-d');

$invoices = LaravelBtcpay::getInvoices($startDate, $endDate);

Refund an invoice

TODO: Add support for pull payments to implement refunds (not currently included)

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email vaibhavraj@vrajroham.me instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.