定制 derrickleemy/laravel-xero-oauth2 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

derrickleemy/laravel-xero-oauth2

Composer 安装命令:

composer require derrickleemy/laravel-xero-oauth2

包简介

A Laravel integration for Xero using the Oauth 2.0 spec

README 文档

README

Latest Version on Packagist Total Downloads

This package integrates the new reccomended package of xeroapi/xero-php-oauth2 using the Oauth 2.0 spec with Laravel.

Installation

You can install this package via composer using the following command:

composer require webfox/laravel-xero-oauth2

The package will automatically register itself.

You can publish the configuration file with:

php artisan vendor:publish --provider="Webfox\Xero\XeroServiceProvider" --tag="config"

You'll want to set the scopes required for your application in the config file.

You should add your Xero keys to your .env file using the following keys:

XERO_CLIENT_ID=
XERO_CLIENT_SECRET=

When setting up the application in Xero ensure your redirect url is https://{your-domain}/xero/auth/callback

Using the Package

This package registers two bindings into the service container you'll be interested in:

  • \XeroAPI\XeroPHP\Api\AccountingApi::class this is the main api for Xero - see the xeroapi/xero-php-oauth2 docs for usage. When you first resolve this dependency if the stored credentials are expired it will automatically refresh the token.
  • Webfox\Xero\OauthCredentialManager this is the credential manager - The Accounting API requires we pass through a tenant ID on each request, this class is how you'd access that. This is also where we can get information about the authenticating user. See below for an example.

app\Http\Controllers\XeroController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Webfox\Xero\OauthCredentialManager;

class XeroController extends Controller
{

    public function index(Request $request, OauthCredentialManager $xeroCredentials)
    {
        try {
            // Check if we've got any stored credentials
            if ($xeroCredentials->exists()) {
                /* 
                 * We have stored credentials so we can resolve the AccountingApi, 
                 * If we were sure we already had some stored credentials then we could just resolve this through the controller
                 * But since we use this route for the initial authentication we cannot be sure!
                 */
                $xero             = resolve(\XeroAPI\XeroPHP\Api\AccountingApi::class);
                $organisationName = $xero->getOrganisations($xeroCredentials->getTenantId())->getOrganisations()[0]->getName();
                $user             = $xeroCredentials->getUser();
                $username         = "{$user['given_name']} {$user['family_name']} ({$user['username']})";
            }
        } catch (\throwable $e) {
            // This can happen if the credentials have been revoked or there is an error with the organisation (e.g. it's expired)
            $error = $e->getMessage();
        }

        return view('xero', [
            'connected'        => $xeroCredentials->exists(),
            'error'            => $error ?? null,
            'organisationName' => $organisationName ?? null,
            'username'         => $username ?? null
        ]);
    }

}

resources\views\xero.blade.php

@extends('_layouts.main')

@section('content')        
@if($error)
    <h1>Your connection to Xero failed</h1>
    <p>{{ $error }}</p>
    <a href="{{ route('xero.auth.authorize') }}" class="btn btn-primary btn-large mt-4">
        Reconnect to Xero
    </a>
@elseif($connected)
    <h1>You are connected to Xero</h1>
    <p>{{ $organisationName }} via {{ $username }}</p>
    <a href="{{ route('xero.auth.authorize') }}" class="btn btn-primary btn-large mt-4">
        Reconnect to Xero
    </a>
@else
    <h1>You are not connected to Xero</h1>
    <a href="{{ route('xero.auth.authorize') }}" class="btn btn-primary btn-large mt-4">
        Connect to Xero
    </a>
@endif
@endsection

routes/web.php

/* 
 * We name this route xero.auth.success as by default the config looks for a route with this name to redirect back to
 * after authentication has succeeded. The name of this route can be changed in the config file.
 */
Route::get('/manage/xero', [\App\Http\Controllers\XeroController::class, 'index'])->name('xero.auth.success');

Using Webhooks

On your application in the Xero developer portal create a webhook to get your webhook key.

You can then add this to your .env file as

XERO_WEBHOOK_KEY=...

You can then setup a controller to handle your webhook and inject \Webfox\Xero\Webhook e.g.

<?php

namespace App\Http\Controllers;

use Webfox\Xero\Webhook;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webfox\Xero\WebhookEvent;
use XeroApi\XeroPHP\Models\Accounting\Contact;
use XeroApi\XeroPHP\Models\Accounting\Invoice;

class XeroWebhookController extends Controller
{
    public function __invoke(Request $request, Webhook $webhook)
    {

        // The following lines are required for Xero's 'itent to receive' validation
        if (!$webhook->validate($request->header('x-xero-signature'))) {
            // We can't use abort here, since Xero expects no response body
            return response('', Response::HTTP_UNAUTHORIZED);
        }

        // A single webhook trigger can contain multiple events, so we must loop over them
        foreach ($webhook->getEvents() as $event) {
            if ($event->getEventType() === 'CREATE' && $event->getEventCategory() === 'INVOICE') {
                $this->invoiceCreated($request, $event->getResource());
            } elseif ($event->getEventType() === 'CREATE' && $event->getEventCategory() === 'CONTACT') {
                $this->contactCreated($request, $event->getResource());
            } elseif ($event->getEventType() === 'UPDATE' && $event->getEventCategory() === 'INVOICE') {
                $this->invoiceUpdated($request, $event->getResource());
            } elseif ($event->getEventType() === 'UPDATE' && $event->getEventCategory() === 'CONTACT') {
                $this->contactUpdated($request, $event->getResource());
            }
        }

        return response('', Response::HTTP_OK);
    }

    protected function invoiceCreated(Request $request, Invoice $invoice)
    {
    }

    protected function contactCreated(Request $request, Contact $contact)
    {
    }

    protected function invoiceUpdated(Request $request, Invoice $invoice)
    {
    }

    protected function contactUpdated(Request $request, Contact $contact)
    {
    }

}

License

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

derrickleemy/laravel-xero-oauth2 适用场景与选型建议

derrickleemy/laravel-xero-oauth2 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 359 次下载、GitHub Stars 达 0, 最近一次更新时间为 2020 年 04 月 14 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「oauth2」 「laravel」 「xero」 「webfox」 「laravel-xero-oauth2」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 derrickleemy/laravel-xero-oauth2 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 derrickleemy/laravel-xero-oauth2 我们能提供哪些服务?
定制开发 / 二次开发

基于 derrickleemy/laravel-xero-oauth2 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 359
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 5
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 37
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2020-04-14