{"id":22740561,"url":"https://github.com/larvatecn/think-transaction","last_synced_at":"2025-04-14T05:53:18.725Z","repository":{"id":57012530,"uuid":"371853183","full_name":"larvatecn/think-transaction","owner":"larvatecn","description":"Transaction Extension for ThinkPHP6.","archived":false,"fork":false,"pushed_at":"2024-01-12T03:08:22.000Z","size":70,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-27T19:50:55.522Z","etag":null,"topics":["pay","payment","payment-gateway","thinkphp","thinkphp6","transaction"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/larvatecn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-29T01:16:30.000Z","updated_at":"2022-06-20T08:04:36.000Z","dependencies_parsed_at":"2022-08-21T13:40:52.194Z","dependency_job_id":null,"html_url":"https://github.com/larvatecn/think-transaction","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larvatecn%2Fthink-transaction","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larvatecn%2Fthink-transaction/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larvatecn%2Fthink-transaction/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larvatecn%2Fthink-transaction/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/larvatecn","download_url":"https://codeload.github.com/larvatecn/think-transaction/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248469583,"owners_count":21109047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pay","payment","payment-gateway","thinkphp","thinkphp6","transaction"],"created_at":"2024-12-10T23:09:23.763Z","updated_at":"2025-04-14T05:53:18.706Z","avatar_url":"https://github.com/larvatecn.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# think-transaction\n\n[![Latest Stable Version](https://poser.pugx.org/larva/think-transaction/v/stable.png)](https://packagist.org/packages/larva/think-transaction)\n[![Total Downloads](https://poser.pugx.org/larva/think-transaction/downloads.png)](https://packagist.org/packages/larva/think-transaction)\n\n\n这是一个内部收单系统，依赖 yansongda/pay 这个组件，本收单系统，统一了调用。\n备注，交易单位是分；\n\n## 环境需求\n\n- PHP \u003e= 7.4.0\n\n## 安装\n\n```shell\n# yansongda/pay 2.x\ncomposer require \"larva/think-transaction:^2.0\"\n\n# yansongda/pay 3.x\ncomposer require \"larva/think-transaction:^3.0\"\n```\n\n由于 `ThinkPHP` 不支持发布迁移文件到应用目录，所以你需要手动复制迁移文件到你应用的迁移目录后执行迁移；\n迁移文件在 `vendor/larva/think-transaction/migrations` 下；\n\n事件\n```php\n\\Larva\\Transaction\\Events\\ChargeClosed 交易已关闭\n\\Larva\\Transaction\\Events\\ChargeFailed 交易失败\n\\Larva\\Transaction\\Events\\ChargeSucceeded 交易已支付\n\\Larva\\Transaction\\Events\\RefundFailed 退款失败事件\n\\Larva\\Transaction\\Events\\RefundSucceeded 退款成功事件\n\\Larva\\Transaction\\Events\\TransferFailed 企业付款（提现）失败事件\n\\Larva\\Transaction\\Events\\TransferSucceeded 企业付款（提现）成功事件\n```\n\n你自己的订单关联参考下面的类，总体思路是你自己的订单模型或者其他需要用户付款的模型在模型创建后你可以用创建后事件来调用付款；\n需要在前端或者APP端执行付款逻辑的时候，你只需要 `$model-\u003echarge-\u003egetCredential();`\n就能获取到付款参数，带入对应的SDK即可，比如APP的SDK需要的几个参数，这里都能获取到。\n`\\Larva\\Transaction\\Events\\ChargeSucceeded` 事件你可以监听到付款成功的事件，\n你只需判断事件的source属性是否是你当前这个模型的实例即可知道是谁触发了付款并且付款成功；\n\n\n```php\nnamespace app\\model;\n\nuse Exception;\nuse Larva\\Transaction\\Models\\Charge;\nuse Larva\\Transaction\\Models\\Refund;\nuse think\\Model;\nuse think\\model\\concern\\SoftDelete;\nuse think\\model\\relation\\MorphOne;\n\n/**\n * 订单模型\n * @property int $id\n * @property int $user_id\n * @property-read boolean $paid\n * @property string $subject\n * @property string $body\n * @property string $amount\n * @property string $channel\n * @property string $type\n * @property string $client_ip\n * @property string $status\n * @property datetime $pay_succeeded_at\n *\n * @property Charge $charge\n *\n * @author Tongle Xu \u003cxutongle@gmail.com\u003e\n */\nclass Order extends Model\n{\n    use SoftDelete;\n\n    const STATUS_PENDING = 'pending';//处理中： pending\n    const STATUS_SUCCEEDED = 'succeeded';//完成： succeeded\n    const STATUS_FAILED = 'failed';//失败： failed\n\n    protected $name = 'orders';\n\n    /**\n     * 新增后会自动触发该事件，这时候就自动创建了付款参数；\n     * @param Order $model\n     */\n    public static function onAfterInsert($model)\n    {\n        $model-\u003echarge()-\u003esave([\n            'user_id' =\u003e $model-\u003euser_id,\n            'amount' =\u003e $model-\u003eamount,//金额单位分\n            'channel' =\u003e $model-\u003echannel,//付款通道 ，如 wechat\n            'subject' =\u003e '订单付款',\n            'body' =\u003e '订单详情',\n            'client_ip' =\u003e $model-\u003eclient_ip,\n            'type' =\u003e $model-\u003etype,//交易类型 如 app\n        ]);\n    }\n\n    /**\n     * Get the entity's charge.\n     *\n     * @return MorphOne\n     */\n    public function charge(): MorphOne\n    {\n        return $this-\u003emorphOne(Charge::class, 'source');\n    }\n\n    /**\n     * 设置交易成功\n     */\n    public function setSucceeded()\n    {\n        $this-\u003eupdate(['channel' =\u003e $this-\u003echarge-\u003echannel, 'status' =\u003e static::STATUS_SUCCEEDED, 'pay_succeeded_at' =\u003e $this-\u003efreshTimestamp()]);\n    }\n\n    /**\n     * 设置交易失败\n     */\n    public function setFailure()\n    {\n        $this-\u003eupdate(['status' =\u003e static::STATUS_FAILED]);\n    }\n\n    /**\n     * 发起退款\n     * @param string $description 退款描述\n     * @return Refund\n     * @throws Exception\n     */\n    public function setRefund(string $description): Refund\n    {\n        if ($this-\u003epaid \u0026\u0026 $this-\u003echarge-\u003eallowRefund) {\n            /** @var Refund $refund */\n            $refund = $this-\u003echarge-\u003erefunds()-\u003esave([\n                'user_id' =\u003e $this-\u003euser_id,\n                'amount' =\u003e $this-\u003eamount,\n                'description' =\u003e $description,\n                'charge_id' =\u003e $this-\u003echarge-\u003eid,\n                'charge_order_id' =\u003e $this-\u003eid,\n            ]);\n            $this-\u003esave(['refunded' =\u003e true]);\n            return $refund;\n        }\n        throw new Exception ('Not paid, no refund.');\n    }\n}\n```\n\n```php\n$order = Order::create([\n    'user_id' =\u003e 1,\n    'subject' =\u003e '标题',\n    'client_ip' =\u003e '192.168.1.1',\n    'amount' =\u003e 100,\n    'channel' =\u003e 'wechat',\n    'type' =\u003e 'app'\n    //你创建订单的参数\n]);\n//获取付款凭证 数组\n$credential = $order-\u003echarge-\u003egetCredential();\n```\n\n创建一个事件监听器 `php think make:subscribe ChargeShipped`\n\n```php\n\u003c?php\ndeclare (strict_types=1);\n\nnamespace app\\subscribe;\n\nuse think\\Event;\n\nclass TransactionCharge\n{\n\n    public function onChargeShipped($charge)\n    {\n        if ($charge-\u003esource instanceof Order) {\n            $charge-\u003esource-\u003esetSucceeded();\n        }\n    }\n\n    public function onChargeClosed($charge)\n    {\n\n    }\n\n    public function onChargeFailure($charge)\n    {\n\n    }\n\n\n    public function subscribe(Event $event)\n    {\n        $event-\u003elisten(\\Larva\\Transaction\\Events\\ChargeClosed::class, [$this, 'onChargeClosed']);\n        $event-\u003elisten(\\Larva\\Transaction\\Events\\ChargeFailed::class, [$this, 'onChargeFailure']);\n        $event-\u003elisten(\\Larva\\Transaction\\Events\\ChargeSucceeded::class, [$this, 'onChargeShipped']);\n    }\n}\n```\n\n在你 `app/event.php` 中加入订阅器如：\n\n```php\n\u003c?php\n// 事件定义文件\nreturn [\n    'bind' =\u003e [\n\n    ],\n\n    'listen' =\u003e [\n        'AppInit' =\u003e [],\n        'HttpRun' =\u003e [],\n        'HttpEnd' =\u003e [\n\n        ],\n        'LogLevel' =\u003e [],\n        'LogWrite' =\u003e [],\n    ],\n\n    'subscribe' =\u003e [\n        'app\\subscribe\\TransactionCharge'\n    ],\n];\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flarvatecn%2Fthink-transaction","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flarvatecn%2Fthink-transaction","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flarvatecn%2Fthink-transaction/lists"}