├── tests ├── PaymentTest.php ├── TossPaymentsBaseTest.php ├── CodeProviderTest.php ├── WebhookTest.php ├── BankCodeTest.php ├── ForeignCardCodeTest.php └── DomesticCardCodeTest.php ├── .gitignore ├── routes └── tosspayments.php ├── src ├── Exceptions │ ├── LargeLimitException.php │ ├── WebhookPayloadException.php │ └── InvalidInputTargetCodeException.php ├── Contracts │ └── AttributeInterface.php ├── Objects │ ├── Vbv.php │ ├── RefundReceiveAccount.php │ └── CashReceipt.php ├── Enums │ ├── ForeignCardCode.php │ ├── CodeProvider.php │ ├── DomesticCardCode.php │ └── BankCode.php ├── Handlers │ └── TossPaymentsWebhookHandler.php ├── TossPaymentsServiceProvider.php ├── Attributes │ ├── Promotion.php │ ├── Transaction.php │ ├── Settlement.php │ ├── CashReceipt.php │ ├── Billing.php │ └── Payment.php └── TossPayments.php ├── .github ├── dependabot.yml ├── workflows │ ├── run-tests.yml │ ├── fix-php-code-style-issues.yml │ └── update-changelog.yml └── ISSUE_TEMPLATE │ └── config.yml ├── config └── tosspayments.php ├── examples ├── TRANSACTION.md ├── PROMOTION.md ├── SETTLEMENT.md ├── CASHRECEIPT.md ├── BILLING.md └── PAYMENT.md ├── phpunit.xml.dist ├── LICENSE.md ├── composer.json ├── README.md └── CHANGELOG.md /tests/PaymentTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Contracts/AttributeInterface.php: -------------------------------------------------------------------------------- 1 | cavv = $cavv; 16 | $this->xid = $xid; 17 | $this->eci = $eci; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Objects/RefundReceiveAccount.php: -------------------------------------------------------------------------------- 1 | bank = $bank; 16 | $this->accountNumber = $accountNumber; 17 | $this->holderName = $holderName; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Objects/CashReceipt.php: -------------------------------------------------------------------------------- 1 | type = $type; 16 | $this->registrationNumber = $registrationNumber; 17 | $this->businessNumber = $businessNumber; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /config/tosspayments.php: -------------------------------------------------------------------------------- 1 | 'https://api.tosspayments.com', 5 | 'version' => 'v1', 6 | 'client_key' => env('TOSS_PAYMENTS_CLIENT_KEY'), 7 | 'secret_key' => env('TOSS_PAYMENTS_SECRET_KEY'), 8 | 'content_type' => 'application/json', 9 | 'accept' => 'application/json', 10 | 11 | 'webhook' => [ 12 | 'handler' => [ 13 | 'controller' => \App\Http\Controllers\WebhookController::class, 14 | 'method' => '__invoke', 15 | ], 16 | ], 17 | ]; 18 | -------------------------------------------------------------------------------- /examples/TRANSACTION.md: -------------------------------------------------------------------------------- 1 | ## [거래 (Transaction)](https://docs.tosspayments.com/reference#%EA%B1%B0%EB%9E%98) 2 | 3 | ### [거래 조회](https://docs.tosspayments.com/reference#%EA%B1%B0%EB%9E%98-%EC%A1%B0%ED%9A%8C) 4 | 5 | GET /v1/transactions 6 | 7 | ```php 8 | use Getsolaris\LaravelTossPayments\TossPayments; 9 | use Getsolaris\LaravelTossPayments\Attributes\Transaction; 10 | 11 | $transactions = TossPayments::for(Transaction::class) 12 | ->startDate('2022-01-01') 13 | ->endDate('2022-12-31') 14 | ->get(); 15 | 16 | return $transactions->json(); 17 | ``` -------------------------------------------------------------------------------- /examples/PROMOTION.md: -------------------------------------------------------------------------------- 1 | ## [카드사 혜택 조회 (Promotion)](https://docs.tosspayments.com/reference#%EC%B9%B4%EB%93%9C%EC%82%AC-%ED%98%9C%ED%83%9D-%EC%A1%B0%ED%9A%8C) 2 | 3 | ### [카드사 혜택 조회](https://docs.tosspayments.com/reference#%EC%B9%B4%EB%93%9C%EC%82%AC-%ED%98%9C%ED%83%9D-%EC%A1%B0%ED%9A%8C-1) 4 | 5 | GET /v1/promotions/card 6 | 7 | ```php 8 | use Getsolaris\LaravelTossPayments\TossPayments; 9 | use Getsolaris\LaravelTossPayments\Attributes\Promotion; 10 | 11 | $promotions = TossPayments::for(Promotion::class) 12 | ->get(); 13 | 14 | return $promotions->json(); 15 | ``` -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: run-tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@v3 12 | 13 | - name: Setup PHP 14 | uses: shivammathur/setup-php@v2 15 | with: 16 | php-version: 8.0 17 | coverage: none 18 | 19 | - name: Install Composer dependencies 20 | run: composer install --prefer-dist --no-interaction 21 | 22 | - name: Execute tests 23 | run: vendor/bin/phpunit tests 24 | -------------------------------------------------------------------------------- /.github/workflows/fix-php-code-style-issues.yml: -------------------------------------------------------------------------------- 1 | name: Fix PHP code style issues 2 | 3 | on: [push] 4 | 5 | jobs: 6 | php-code-styling: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@v3 12 | with: 13 | ref: ${{ github.head_ref }} 14 | 15 | - name: Fix PHP code style issues 16 | uses: aglipanci/laravel-pint-action@1.0.0 17 | 18 | - name: Commit changes 19 | uses: stefanzweifel/git-auto-commit-action@v4 20 | with: 21 | commit_message: "style: fix psr-12 code style issues" 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Ask a question 4 | url: https://github.com/getsolaris/laravel-aws-secretsmanager/discussions/new?category=q-a 5 | about: Ask the community for help 6 | - name: Request a feature 7 | url: https://github.com/getsolaris/laravel-aws-secretsmanager/discussions/new?category=ideas 8 | about: Share ideas for new features 9 | - name: Report a security issue 10 | url: https://github.com/getsolaris/laravel-aws-secretsmanager/security/policy 11 | about: Learn how to notify us for sensitive bugs 12 | - name: Report a bug 13 | url: https://github.com/getsolaris/laravel-aws-secretsmanager/issues/new 14 | about: Report a reproducible bug 15 | -------------------------------------------------------------------------------- /src/Enums/ForeignCardCode.php: -------------------------------------------------------------------------------- 1 | '6D', 9 | 'kr' => '다이너스', 10 | ]; 11 | 12 | public const DISCOVER = [ 13 | 'code' => '6I', 14 | 'kr' => '디스커버', 15 | ]; 16 | 17 | public const MASTER = [ 18 | 'code' => '4M', 19 | 'kr' => '마스터', 20 | ]; 21 | 22 | public const UNIONPAY = [ 23 | 'code' => '3C', 24 | 'kr' => '유니온페이', 25 | ]; 26 | 27 | public const JCB = [ 28 | 'code' => '4J', 29 | 'kr' => null, 30 | ]; 31 | 32 | public const VISA = [ 33 | 'code' => '4V', 34 | 'kr' => '비자', 35 | ]; 36 | } 37 | -------------------------------------------------------------------------------- /.github/workflows/update-changelog.yml: -------------------------------------------------------------------------------- 1 | name: "Update Changelog" 2 | 3 | on: 4 | release: 5 | types: [released] 6 | 7 | jobs: 8 | update: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v3 14 | with: 15 | ref: main 16 | 17 | - name: Update Changelog 18 | uses: stefanzweifel/changelog-updater-action@v1 19 | with: 20 | latest-version: ${{ github.event.release.name }} 21 | release-notes: ${{ github.event.release.body }} 22 | 23 | - name: Commit updated CHANGELOG 24 | uses: stefanzweifel/git-auto-commit-action@v4 25 | with: 26 | branch: main 27 | commit_message: Update CHANGELOG 28 | file_pattern: CHANGELOG.md 29 | -------------------------------------------------------------------------------- /tests/CodeProviderTest.php: -------------------------------------------------------------------------------- 1 | expectException(LogicException::class); 25 | CodeProvider::toCode(self::TEST_TOSSBANK_CODE); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/WebhookTest.php: -------------------------------------------------------------------------------- 1 | getData(); 12 | 13 | $this->assertIsArray($payload); 14 | $this->assertArrayHasKey('eventType', $payload); 15 | $this->assertArrayHasKey('createdAt', $payload); 16 | $this->assertArrayHasKey('data', $payload); 17 | $this->assertIsArray($payload['data']); 18 | } 19 | 20 | private function getData(): array 21 | { 22 | $payload = '{ 23 | "eventType": "PAYMENT_STATUS_CHANGED", 24 | "createdAt": "2022-01-01T00:00:00.000000", 25 | "data": {} 26 | }'; 27 | 28 | return json_decode($payload, true); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Handlers/TossPaymentsWebhookHandler.php: -------------------------------------------------------------------------------- 1 | getContent(), true, 512, JSON_THROW_ON_ERROR); 18 | 19 | if (! $payload) { 20 | throw new WebhookPayloadException; 21 | } 22 | 23 | $target = new \ReflectionClass(config('tosspayments.webhook.handler.controller')); 24 | $method = config('tosspayments.webhook.handler.method'); 25 | 26 | return $target->newInstance()->$method($payload); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | ./tests 19 | 20 | 21 | 22 | 23 | ./src 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/SETTLEMENT.md: -------------------------------------------------------------------------------- 1 | ## [정산 (Settlement)](https://docs.tosspayments.com/reference#%EC%A0%95%EC%82%B0) 2 | 3 | ### [정산 조회](https://docs.tosspayments.com/reference#%EC%A0%95%EC%82%B0-%EC%A1%B0%ED%9A%8C) 4 | 5 | GET /v1/settlements 6 | 7 | ```php 8 | use Getsolaris\LaravelTossPayments\TossPayments; 9 | use Getsolaris\LaravelTossPayments\Attributes\Settlement; 10 | 11 | $settlements = TossPayments::for(Settlement::class) 12 | ->startDate($startDate) 13 | ->endDate($endDate) 14 | ->get(); 15 | 16 | return $settlements->json(); 17 | ``` 18 | 19 | ### [수동 정산 요청](https://docs.tosspayments.com/reference#%EC%88%98%EB%8F%99-%EC%A0%95%EC%82%B0-%EC%9A%94%EC%B2%AD) 20 | 21 | POST /v1/settlements 22 | 23 | ```php 24 | use Getsolaris\LaravelTossPayments\TossPayments; 25 | use Getsolaris\LaravelTossPayments\Attributes\Settlement; 26 | 27 | $settlement = TossPayments::for(Settlement::class) 28 | ->paymentKey($paymentKey) 29 | ->request(); 30 | 31 | return $settlement->json(); 32 | ``` 33 | -------------------------------------------------------------------------------- /src/TossPaymentsServiceProvider.php: -------------------------------------------------------------------------------- 1 | mergeConfigFrom(__DIR__."/../config/{$this->name}.php", $this->name); 14 | 15 | $this->app->bind(TossPayments::class, function ($app) { 16 | return TossPayments::for($app['request']); 17 | }); 18 | } 19 | 20 | public function boot(): void 21 | { 22 | $this->publishes([ 23 | __DIR__."/../config/{$this->name}.php" => config_path($this->name.'.php'), 24 | ], 'config'); 25 | 26 | $this->publishes([ 27 | __DIR__."/../routes/{$this->name}.php" => base_path('routes/'.$this->name.'.php'), 28 | ], 'webhook'); 29 | 30 | $this->loadRoutesFrom(__DIR__."/../routes/{$this->name}.php"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) getsolaris 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/Attributes/Promotion.php: -------------------------------------------------------------------------------- 1 | initializeUri(); 18 | } 19 | 20 | public function initializeUri(): static 21 | { 22 | $this->uri = '/promotions'; 23 | 24 | return $this; 25 | } 26 | 27 | public function createEndpoint(?string $endpoint, bool $withUri = true): string 28 | { 29 | if ($withUri) { 30 | return $this->url.$this->uri.$this->start($endpoint); 31 | } 32 | 33 | return $this->url.$this->start($endpoint); 34 | } 35 | 36 | public function get(): PromiseInterface|Response 37 | { 38 | return $this->client->get($this->createEndpoint('/card')); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Enums/CodeProvider.php: -------------------------------------------------------------------------------- 1 | getConstants(); 26 | foreach ($constants as $constant) { 27 | if ($constant['code'] === $code) { 28 | return $constant['code']; 29 | } 30 | 31 | if ($constant['kr'] === $code) { 32 | return $constant['code']; 33 | } 34 | } 35 | 36 | throw new InvalidInputTargetCodeException; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getsolaris/laravel-tosspayments", 3 | "description": "A Laravel package to Toss Payments", 4 | "keywords": [ 5 | "getsolaris", 6 | "laravel", 7 | "toss", 8 | "tosspayments" 9 | ], 10 | "homepage": "https://github.com/getsolaris/laravel-toss-payments", 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "getsolaris", 15 | "email": "im@getsolaris.kr" 16 | } 17 | ], 18 | "support": { 19 | "issues": "https://github.com/getsolaris/laravel-toss-payments/issues", 20 | "source": "https://github.com/getsolaris/laravel-toss-payments" 21 | }, 22 | "require": { 23 | "php": "^8.0", 24 | "ext-json": "*", 25 | "illuminate/support": "^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0 ||^12.0" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "^9.5" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Getsolaris\\LaravelTossPayments\\": "src" 33 | } 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "Getsolaris\\LaravelTossPayments\\Tests\\": "tests" 38 | } 39 | }, 40 | "config": { 41 | "sort-packages": true 42 | }, 43 | "extra": { 44 | "laravel": { 45 | "providers": [ 46 | "Getsolaris\\LaravelTossPayments\\TossPaymentsServiceProvider" 47 | ], 48 | "aliases": { 49 | "AwsSecretsManager": "Getsolaris\\LaravelTossPayments\\TossPayments" 50 | } 51 | } 52 | }, 53 | "minimum-stability": "dev", 54 | "prefer-stable": true 55 | } 56 | -------------------------------------------------------------------------------- /examples/CASHRECEIPT.md: -------------------------------------------------------------------------------- 1 | ## [현금영수증 (CashReceipt)](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D) 2 | 3 | ### [현금영수증 발급](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D) 4 | 5 | POST /v1/cash-receipts 6 | 7 | ```php 8 | use Getsolaris\LaravelTossPayments\TossPayments; 9 | use Getsolaris\LaravelTossPayments\Attributes\CashReceipt; 10 | 11 | $cashReceipt = TossPayments::for(CashReceipt::class) 12 | ->amount($amount) 13 | ->orderId($orderId) 14 | ->orderName($orderName) 15 | ->customerIdentityNumber($customerIdentityNumber) 16 | ->type($type) 17 | ->request(); 18 | 19 | return $cashReceipt->json(); 20 | ``` 21 | 22 | ### [현금영수증 발급 취소](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D-%EB%B0%9C%EA%B8%89-%EC%B7%A8%EC%86%8C) 23 | 24 | POST /v1/cash-receipts/{receiptKey}/cancel 25 | 26 | ```php 27 | use Getsolaris\LaravelTossPayments\TossPayments; 28 | use Getsolaris\LaravelTossPayments\Attributes\CashReceipt; 29 | 30 | $cashReceipt = TossPayments::for(CashReceipt::class) 31 | ->receiptKey($receiptKey) 32 | ->cancel(); 33 | 34 | return $cashReceipt->json(); 35 | ``` 36 | 37 | ### [현금영수증 조회](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D-%EC%A1%B0%ED%9A%8C) 38 | 39 | GET /v1/cash-receipts 40 | 41 | ```php 42 | use Getsolaris\LaravelTossPayments\TossPayments; 43 | use Getsolaris\LaravelTossPayments\Attributes\CashReceipt; 44 | 45 | $cashReceipts = TossPayments::for(CashReceipt::class) 46 | ->requestDate($requestDate) 47 | ->get(); 48 | 49 | return $cashReceipts->json(); 50 | ``` -------------------------------------------------------------------------------- /tests/BankCodeTest.php: -------------------------------------------------------------------------------- 1 | assertSame(self::TEST_TOSSBANK_CODE, $code); 24 | } 25 | 26 | /** 27 | * 영문으로 입력된 경우 코드로 변환 28 | * 29 | * 30 | * @throws InvalidInputTargetCodeException 31 | * @throws \ReflectionException 32 | */ 33 | public function test_convert_en_to_code(): void 34 | { 35 | $code = BankCode::toCode('TOSSBANK'); 36 | $this->assertSame(self::TEST_TOSSBANK_CODE, $code); 37 | } 38 | 39 | /** 40 | * 코드로 입력된 경우 올바른 코드인지 확인 후 반환 41 | * 42 | * 43 | * @throws InvalidInputTargetCodeException 44 | * @throws \ReflectionException 45 | */ 46 | public function test_always_code(): void 47 | { 48 | $code = BankCode::toCode(self::TEST_TOSSBANK_CODE); 49 | $this->assertSame(self::TEST_TOSSBANK_CODE, $code); 50 | } 51 | 52 | /** 53 | * 올바르지 않은 코드가 입력된 경우 예외처리 발생 54 | * 55 | * 56 | * @throws InvalidInputTargetCodeException 57 | * @throws \ReflectionException 58 | */ 59 | public function test_invalid_input_target_code_exception(): void 60 | { 61 | $this->expectException(InvalidInputTargetCodeException::class); 62 | BankCode::toCode('invalid'); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/ForeignCardCodeTest.php: -------------------------------------------------------------------------------- 1 | assertSame(self::TEST_VISA_CODE, $code); 24 | } 25 | 26 | /** 27 | * 영문으로 입력된 경우 코드로 변환 28 | * 29 | * 30 | * @throws InvalidInputTargetCodeException 31 | * @throws \ReflectionException 32 | */ 33 | public function test_convert_en_to_code(): void 34 | { 35 | $code = ForeignCardCode::toCode('VISA'); 36 | $this->assertSame(self::TEST_VISA_CODE, $code); 37 | } 38 | 39 | /** 40 | * 코드로 입력된 경우 올바른 코드인지 확인 후 반환 41 | * 42 | * 43 | * @throws InvalidInputTargetCodeException 44 | * @throws \ReflectionException 45 | */ 46 | public function test_always_code(): void 47 | { 48 | $code = ForeignCardCode::toCode(self::TEST_VISA_CODE); 49 | $this->assertSame(self::TEST_VISA_CODE, $code); 50 | } 51 | 52 | /** 53 | * 올바르지 않은 코드가 입력된 경우 예외처리 발생 54 | * 55 | * 56 | * @throws InvalidInputTargetCodeException 57 | * @throws \ReflectionException 58 | */ 59 | public function test_invalid_input_target_code_exception(): void 60 | { 61 | $this->expectException(InvalidInputTargetCodeException::class); 62 | ForeignCardCode::toCode('invalid'); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/DomesticCardCodeTest.php: -------------------------------------------------------------------------------- 1 | assertSame(self::TEST_TOSSBANK_CODE, $code); 24 | } 25 | 26 | /** 27 | * 영문으로 입력된 경우 코드로 변환 28 | * 29 | * 30 | * @throws InvalidInputTargetCodeException 31 | * @throws \ReflectionException 32 | */ 33 | public function test_convert_en_to_code(): void 34 | { 35 | $code = DomesticCardCode::toCode('TOSSBANK'); 36 | $this->assertSame(self::TEST_TOSSBANK_CODE, $code); 37 | } 38 | 39 | /** 40 | * 코드로 입력된 경우 올바른 코드인지 확인 후 반환 41 | * 42 | * 43 | * @throws InvalidInputTargetCodeException 44 | * @throws \ReflectionException 45 | */ 46 | public function test_always_code(): void 47 | { 48 | $code = DomesticCardCode::toCode(self::TEST_TOSSBANK_CODE); 49 | $this->assertSame(self::TEST_TOSSBANK_CODE, $code); 50 | } 51 | 52 | /** 53 | * 올바르지 않은 코드가 입력된 경우 예외처리 발생 54 | * 55 | * 56 | * @throws InvalidInputTargetCodeException 57 | * @throws \ReflectionException 58 | */ 59 | public function test_invalid_input_target_code_exception(): void 60 | { 61 | $this->expectException(InvalidInputTargetCodeException::class); 62 | DomesticCardCode::toCode('invalid'); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /examples/BILLING.md: -------------------------------------------------------------------------------- 1 | ## [자동 결제 (Billing)](https://docs.tosspayments.com/reference#%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C) 2 | 3 | ### [customerKey로 카드 자동 결제 빌링키 발급 요청](https://docs.tosspayments.com/reference#customerkey%EB%A1%9C-%EC%B9%B4%EB%93%9C-%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C-%EB%B9%8C%EB%A7%81%ED%82%A4-%EB%B0%9C%EA%B8%89-%EC%9A%94%EC%B2%AD) 4 | 5 | POST /v1/billing/authorizations/card 6 | 7 | ```php 8 | use Getsolaris\LaravelTossPayments\TossPayments; 9 | use Getsolaris\LaravelTossPayments\Attributes\Billing; 10 | 11 | $billing = TossPayments::for(Billing::class) 12 | ->customerKey($customerKey) 13 | ->cardNumber($cardNumber) 14 | ->cardExpirationYear($cardExpirationYear) 15 | ->cardExpirationMonth($cardExpirationMonth) 16 | ->customerIdentityNumber($customerIdentityNumber) 17 | ->authorizationsCard(); 18 | 19 | return $billing->json(); 20 | ``` 21 | 22 | ### [authKey로 카드 자동 결제 빌링키 발급 요청](https://docs.tosspayments.com/reference#authkey%EB%A1%9C-%EC%B9%B4%EB%93%9C-%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C-%EB%B9%8C%EB%A7%81%ED%82%A4-%EB%B0%9C%EA%B8%89-%EC%9A%94%EC%B2%AD) 23 | 24 | POST /v1/billing/authorizations/issue 25 | 26 | ```php 27 | use Getsolaris\LaravelTossPayments\TossPayments; 28 | use Getsolaris\LaravelTossPayments\Attributes\Billing; 29 | 30 | $billing = TossPayments::for(Billing::class) 31 | ->customerKey($customerKey) 32 | ->authKey($authKey) 33 | ->authorizationsIssue(); 34 | 35 | return $billing->json(); 36 | ``` 37 | 38 | ### [카드 자동 결제 승인 요청](https://docs.tosspayments.com/reference#%EC%B9%B4%EB%93%9C-%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C-%EC%8A%B9%EC%9D%B8-%EC%9A%94%EC%B2%AD) 39 | 40 | POST /v1/billing/{billingKey} 41 | 42 | ```php 43 | use Getsolaris\LaravelTossPayments\TossPayments; 44 | use Getsolaris\LaravelTossPayments\Attributes\Billing; 45 | 46 | $billing = TossPayments::for(Billing::class) 47 | ->customerKey($customerKey) 48 | ->authKey($authKey) 49 | ->authorizationsIssue(); 50 | 51 | return $billing->json(); 52 | ``` -------------------------------------------------------------------------------- /src/Attributes/Transaction.php: -------------------------------------------------------------------------------- 1 | initializeUri(); 23 | } 24 | 25 | /** 26 | * @return $this 27 | */ 28 | public function initializeUri(): static 29 | { 30 | $this->uri = '/transactions'; 31 | 32 | return $this; 33 | } 34 | 35 | public function createEndpoint(?string $endpoint, bool $withUri = true): string 36 | { 37 | if ($withUri) { 38 | return $this->url.$this->uri.$this->start($endpoint); 39 | } 40 | 41 | return $this->url.$this->start($endpoint); 42 | } 43 | 44 | /** 45 | * @return $this 46 | */ 47 | public function startDate(string $startDate): static 48 | { 49 | $this->startDate = $startDate; 50 | 51 | return $this; 52 | } 53 | 54 | /** 55 | * @return $this 56 | */ 57 | public function endDate(string $endDate): static 58 | { 59 | $this->endDate = $endDate; 60 | 61 | return $this; 62 | } 63 | 64 | /** 65 | * @throws LargeLimitException 66 | */ 67 | public function get(?string $startingAfter = null, ?int $limit = null): PromiseInterface|Response 68 | { 69 | $parameters = []; 70 | if ($startingAfter) { 71 | $parameters['startingAfter'] = $startingAfter; 72 | } 73 | 74 | if ($limit) { 75 | if ($limit > 10000) { 76 | throw new LargeLimitException; 77 | } 78 | 79 | $parameters['limit'] = $limit; 80 | } 81 | 82 | return $this->client->get($this->createEndpoint('/'), [ 83 | 'startDate' => $this->startDate, 84 | 'endDate' => $this->endDate, 85 | ] + $parameters); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Enums/DomesticCardCode.php: -------------------------------------------------------------------------------- 1 | 46, 9 | 'kr' => '광주', 10 | ]; 11 | 12 | public const LOTTE = [ 13 | 'code' => 71, 14 | 'kr' => '롯데', 15 | ]; 16 | 17 | public const KDBBANK = [ 18 | 'code' => 30, 19 | 'kr' => '산업', 20 | ]; 21 | 22 | public const BC = [ 23 | 'code' => 31, 24 | 'kr' => null, 25 | ]; 26 | 27 | public const SAMSUNG = [ 28 | 'code' => 51, 29 | 'kr' => '삼성', 30 | ]; 31 | 32 | public const SAEMAUL = [ 33 | 'code' => 38, 34 | 'kr' => '새마을', 35 | ]; 36 | 37 | public const SHINHAN = [ 38 | 'code' => 41, 39 | 'kr' => '신한', 40 | ]; 41 | 42 | public const SHINHYEOP = [ 43 | 'code' => 62, 44 | 'kr' => '신협', 45 | ]; 46 | 47 | public const CITI = [ 48 | 'code' => 36, 49 | 'kr' => '씨티', 50 | ]; 51 | 52 | public const WOORI = [ 53 | 'code' => 33, 54 | 'kr' => '우리', 55 | ]; 56 | 57 | public const POST = [ 58 | 'code' => 37, 59 | 'kr' => '우체국', 60 | ]; 61 | 62 | public const SAVINGBANK = [ 63 | 'code' => 39, 64 | 'kr' => '저축', 65 | ]; 66 | 67 | public const JEONBUKBANK = [ 68 | 'code' => 35, 69 | 'kr' => '전북', 70 | ]; 71 | 72 | public const JEJUBANK = [ 73 | 'code' => 42, 74 | 'kr' => '제주', 75 | ]; 76 | 77 | public const KAKAOBANK = [ 78 | 'code' => 15, 79 | 'kr' => '카카오뱅크', 80 | ]; 81 | 82 | public const KBANK = [ 83 | 'code' => '3A', 84 | 'kr' => '케이뱅크', 85 | ]; 86 | 87 | public const TOSSBANK = [ 88 | 'code' => 24, 89 | 'kr' => '토스뱅크', 90 | ]; 91 | 92 | public const HANA = [ 93 | 'code' => 21, 94 | 'kr' => '하나', 95 | ]; 96 | 97 | public const HYUNDAI = [ 98 | 'code' => 61, 99 | 'kr' => '현대', 100 | ]; 101 | 102 | public const KOOKMIN = [ 103 | 'code' => 11, 104 | 'kr' => '국민', 105 | ]; 106 | 107 | public const NONGHYEOP = [ 108 | 'code' => 91, 109 | 'kr' => '농협', 110 | ]; 111 | 112 | public const SUHYEOP = [ 113 | 'code' => 34, 114 | 'kr' => '수협', 115 | ]; 116 | } 117 | -------------------------------------------------------------------------------- /src/Attributes/Settlement.php: -------------------------------------------------------------------------------- 1 | initializeUri(); 24 | } 25 | 26 | /** 27 | * @return $this 28 | */ 29 | public function initializeUri(): static 30 | { 31 | $this->uri = '/settlements'; 32 | 33 | return $this; 34 | } 35 | 36 | public function createEndpoint(?string $endpoint, bool $withUri = true): string 37 | { 38 | if ($withUri) { 39 | return $this->url.$this->uri.$this->start($endpoint); 40 | } 41 | 42 | return $this->url.$this->start($endpoint); 43 | } 44 | 45 | /** 46 | * @return $this 47 | */ 48 | public function startDate(string $startDate): static 49 | { 50 | $this->startDate = $startDate; 51 | 52 | return $this; 53 | } 54 | 55 | /** 56 | * @return $this 57 | */ 58 | public function endDate(string $endDate): static 59 | { 60 | $this->endDate = $endDate; 61 | 62 | return $this; 63 | } 64 | 65 | public function get( 66 | ?string $dataType = null, 67 | ?int $page = null, 68 | ?int $size = null 69 | ): PromiseInterface|Response { 70 | $parameters = []; 71 | if ($dataType) { 72 | $parameters['dataType'] = $dataType; 73 | } 74 | 75 | if ($page) { 76 | $parameters['page'] = $page; 77 | } 78 | 79 | if ($size) { 80 | $parameters['size'] = $size; 81 | } 82 | 83 | return $this->client->get($this->createEndpoint('/'), [ 84 | 'startDate' => $this->startDate, 85 | 'endDate' => $this->endDate, 86 | ] + $parameters); 87 | } 88 | 89 | /** 90 | * @return $this 91 | */ 92 | public function paymentKey(string $paymentKey): static 93 | { 94 | $this->paymentKey = $paymentKey; 95 | 96 | return $this; 97 | } 98 | 99 | public function request(): PromiseInterface|Response 100 | { 101 | return $this->client->get($this->createEndpoint('/'), [ 102 | 'paymentKey' => $this->paymentKey, 103 | ]); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Enums/BankCode.php: -------------------------------------------------------------------------------- 1 | 39, 9 | 'kr' => '경남', 10 | ]; 11 | 12 | public const GWANGJUBANK = [ 13 | 'code' => 34, 14 | 'kr' => '광주', 15 | ]; 16 | 17 | public const LOCALNONGHYEOP = [ 18 | 'code' => 12, 19 | 'kr' => '단위농협', 20 | ]; 21 | 22 | public const BUSANBANK = [ 23 | 'code' => 32, 24 | 'kr' => '부산', 25 | ]; 26 | 27 | public const SAEMAUL = [ 28 | 'code' => 45, 29 | 'kr' => '새마을', 30 | ]; 31 | 32 | public const SANLIM = [ 33 | 'code' => 64, 34 | 'kr' => '산림', 35 | ]; 36 | 37 | public const SHINHAN = [ 38 | 'code' => 88, 39 | 'kr' => '신한', 40 | ]; 41 | 42 | public const SHINHYEOP = [ 43 | 'code' => 48, 44 | 'kr' => '신협', 45 | ]; 46 | 47 | public const CITI = [ 48 | 'code' => 27, 49 | 'kr' => '씨티', 50 | ]; 51 | 52 | public const WOORI = [ 53 | 'code' => 20, 54 | 'kr' => '우리', 55 | ]; 56 | 57 | public const POST = [ 58 | 'code' => 71, 59 | 'kr' => '우체국', 60 | ]; 61 | 62 | public const SAVINGBANK = [ 63 | 'code' => 50, 64 | 'kr' => '저축', 65 | ]; 66 | 67 | public const JEONBUKBANK = [ 68 | 'code' => 37, 69 | 'kr' => '전북', 70 | ]; 71 | 72 | public const JEJUBANK = [ 73 | 'code' => 35, 74 | 'kr' => '제주', 75 | ]; 76 | 77 | public const KAKAOBANK = [ 78 | 'code' => 90, 79 | 'kr' => '카카오', 80 | ]; 81 | 82 | public const KBANK = [ 83 | 'code' => 89, 84 | 'kr' => '케이', 85 | ]; 86 | 87 | public const TOSSBANK = [ 88 | 'code' => 92, 89 | 'kr' => '토스', 90 | ]; 91 | 92 | public const HANA = [ 93 | 'code' => 81, 94 | 'kr' => '하나', 95 | ]; 96 | 97 | public const HSBC = [ 98 | 'code' => 54, 99 | 'kr' => null, 100 | ]; 101 | 102 | public const DAEGUBANK = [ 103 | 'code' => 31, 104 | 'kr' => '대구', 105 | ]; 106 | 107 | public const IBK = [ 108 | 'code' => 03, 109 | 'kr' => '기업', 110 | ]; 111 | 112 | public const KDBBANK = [ 113 | 'code' => 02, 114 | 'kr' => '산업', 115 | ]; 116 | 117 | public const KOOKMIN = [ 118 | 'code' => 06, 119 | 'kr' => '국민', 120 | ]; 121 | 122 | public const NONGHYEOP = [ 123 | 'code' => 11, 124 | 'kr' => '농협', 125 | ]; 126 | 127 | public const SC = [ 128 | 'code' => 23, 129 | 'kr' => 'SC제일', 130 | ]; 131 | 132 | public const SUHYEOP = [ 133 | 'code' => 07, 134 | 'kr' => '수협', 135 | ]; 136 | } 137 | -------------------------------------------------------------------------------- /src/TossPayments.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute) 29 | ->initializeApiUrl() 30 | ->initializeKeys() 31 | ->initializeHeaders() 32 | ->initializeHttp(); 33 | } 34 | 35 | /** 36 | * @return $this 37 | */ 38 | public function setAttribute($attribute): static 39 | { 40 | $this->attribute = $attribute; 41 | 42 | return $this; 43 | } 44 | 45 | public static function for($attribute): static 46 | { 47 | return new static(new $attribute); 48 | } 49 | 50 | /** 51 | * @return TossPayments 52 | */ 53 | public function __call($name, $arguments) 54 | { 55 | return $this->attribute->{$name}(...$arguments); 56 | } 57 | 58 | /** 59 | * @return $this 60 | */ 61 | protected function initializeApiUrl(): static 62 | { 63 | $this->endpoint = config('tosspayments.endpoint'); 64 | $this->version = config('tosspayments.version'); 65 | $this->url = $this->endpoint.'/'.$this->version; 66 | 67 | return $this; 68 | } 69 | 70 | /** 71 | * @return $this 72 | */ 73 | protected function initializeKeys(): static 74 | { 75 | $this->clientKey = config('tosspayments.client_key'); 76 | $this->secretKey = config('tosspayments.secret_key'); 77 | 78 | return $this; 79 | } 80 | 81 | /** 82 | * @return $this 83 | */ 84 | protected function initializeHeaders(): static 85 | { 86 | $this->headers = [ 87 | 'Authorization' => 'Basic '.base64_encode($this->secretKey.':'), 88 | 'Content-Type' => 'application/json', 89 | ]; 90 | 91 | return $this; 92 | } 93 | 94 | /** 95 | * @return $this 96 | */ 97 | protected function initializeHttp(): static 98 | { 99 | $this->client = Http::withHeaders($this->headers); 100 | 101 | return $this; 102 | } 103 | 104 | public function start(string $value, string $prefix = '/'): string 105 | { 106 | return Str::start($value, $prefix); 107 | } 108 | 109 | /** 110 | * @return $this 111 | */ 112 | protected function testCode(string $code): static 113 | { 114 | $this->client = Http::withHeaders($this->headers + ['TossPayments-Test-Code' => $code]); 115 | 116 | return $this; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /examples/PAYMENT.md: -------------------------------------------------------------------------------- 1 | ## [결제 (Payment)](https://docs.tosspayments.com/reference#%EA%B2%B0%EC%A0%9C) 2 | 3 | ### [결제승인](https://docs.tosspayments.com/reference#%EA%B2%B0%EC%A0%9C-%EC%8A%B9%EC%9D%B8) 4 | 5 | POST /v1/payments/confirm 6 | 7 | ```php 8 | use Getsolaris\LaravelTossPayments\TossPayments; 9 | use Getsolaris\LaravelTossPayments\Attributes\Payment; 10 | 11 | $payment = TossPayments::for(Payment::class) 12 | ->paymentKey($paymentKey) 13 | ->orderId($orderId) 14 | ->amount($amount) 15 | ->confirm(); 16 | 17 | return $payment->json(); 18 | ``` 19 | 20 | ### [paymentKey로 결제 조회](https://docs.tosspayments.com/reference#paymentkey%EB%A1%9C-%EA%B2%B0%EC%A0%9C-%EC%A1%B0%ED%9A%8C) 21 | 22 | GET /v1/payments/{paymentKey} 23 | 24 | ```php 25 | use Getsolaris\LaravelTossPayments\TossPayments; 26 | use Getsolaris\LaravelTossPayments\Attributes\Payment; 27 | 28 | $payment = TossPayments::for(Payment::class) 29 | ->paymentKey($paymentKey) 30 | ->get(); 31 | 32 | return $payment->json(); 33 | ``` 34 | 35 | ### [orderId로 결제 조회](https://docs.tosspayments.com/reference#orderid%EB%A1%9C-%EA%B2%B0%EC%A0%9C-%EC%A1%B0%ED%9A%8C) 36 | 37 | GET /v1/payments/orders/{orderId} 38 | 39 | ```php 40 | use Getsolaris\LaravelTossPayments\TossPayments; 41 | use Getsolaris\LaravelTossPayments\Attributes\Payment; 42 | 43 | $payment = TossPayments::for(Payment::class) 44 | ->orderId($orderId) 45 | ->get(); 46 | 47 | return $payment->json(); 48 | ``` 49 | 50 | ### [결제 취소](https://docs.tosspayments.com/reference#%EA%B2%B0%EC%A0%9C-%EC%B7%A8%EC%86%8C) 51 | 52 | POST /v1/payments/{paymentKey}/cancel 53 | 54 | ```php 55 | use Getsolaris\LaravelTossPayments\TossPayments; 56 | use Getsolaris\LaravelTossPayments\Attributes\Payment; 57 | 58 | $payment = TossPayments::for(Payment::class) 59 | ->paymentKey($paymentKey) 60 | ->cancelReason('고객 변심') 61 | ->cancel( 62 | refundReceiveAccount: new RefundReceiveAccount( 63 | bank: '11', 64 | accountNumber: '111111111111', 65 | holderName: '홍길동' 66 | ) 67 | ); 68 | 69 | return $payment->json(); 70 | ``` 71 | 72 | ### [카드 번호 결제](https://docs.tosspayments.com/reference#%EC%B9%B4%EB%93%9C-%EB%B2%88%ED%98%B8-%EA%B2%B0%EC%A0%9C) 73 | 74 | POST /v1/payments/key-in 75 | 76 | ```php 77 | use Getsolaris\LaravelTossPayments\TossPayments; 78 | use Getsolaris\LaravelTossPayments\Attributes\Payment; 79 | 80 | $keyIn = TossPayments::for(Payment::class) 81 | ->amount($amount) 82 | ->orderId($orderId) 83 | ->orderName($orderName) 84 | ->cardNumber($cardNumber) 85 | ->cardExpirationYear($cardExpirationYear) 86 | ->cardExpirationMonth($cardExpirationMonth) 87 | ->customerIdentityNumber($customerIdentityNumber) 88 | ->keyIn(); 89 | 90 | return $keyIn->json(); 91 | ``` 92 | 93 | 94 | ### [가상계좌 발급 요청](https://docs.tosspayments.com/reference#%EA%B0%80%EC%83%81%EA%B3%84%EC%A2%8C-%EB%B0%9C%EA%B8%89-%EC%9A%94%EC%B2%AD) 95 | 96 | POST /v1/virtual-accounts 97 | 98 | ```php 99 | use Getsolaris\LaravelTossPayments\TossPayments; 100 | use Getsolaris\LaravelTossPayments\Attributes\Payment; 101 | 102 | $virtualAccounts = TossPayments::for(Payment::class) 103 | ->amount($amount) 104 | ->orderId($orderId) 105 | ->orderName($orderName) 106 | ->customerName($customerName) 107 | ->bank('우리') 108 | ->virtualAccounts(); 109 | 110 | return $virtualAccounts->json(); 111 | ``` -------------------------------------------------------------------------------- /src/Attributes/CashReceipt.php: -------------------------------------------------------------------------------- 1 | initializeUri(); 32 | } 33 | 34 | /** 35 | * @return $this 36 | */ 37 | public function initializeUri(): static 38 | { 39 | $this->uri = '/cash-receipts'; 40 | 41 | return $this; 42 | } 43 | 44 | public function createEndpoint(?string $endpoint, bool $withUri = true): string 45 | { 46 | if ($withUri) { 47 | return $this->url.$this->uri.$this->start($endpoint); 48 | } 49 | 50 | return $this->url.$this->start($endpoint); 51 | } 52 | 53 | /** 54 | * @return $this 55 | */ 56 | public function receiptKey(string $receiptKey): static 57 | { 58 | $this->receiptKey = $receiptKey; 59 | 60 | return $this; 61 | } 62 | 63 | /** 64 | * @return $this 65 | */ 66 | public function amount(int $amount): static 67 | { 68 | $this->amount = $amount; 69 | 70 | return $this; 71 | } 72 | 73 | /** 74 | * @return $this 75 | */ 76 | public function orderId(string $orderId): static 77 | { 78 | $this->orderId = $orderId; 79 | 80 | return $this; 81 | } 82 | 83 | /** 84 | * @return $this 85 | */ 86 | public function orderName(string $orderName): static 87 | { 88 | $this->orderName = $orderName; 89 | 90 | return $this; 91 | } 92 | 93 | /** 94 | * @return $this 95 | */ 96 | public function customerIdentityNumber(string $customerIdentityNumber): static 97 | { 98 | $this->customerIdentityNumber = $customerIdentityNumber; 99 | 100 | return $this; 101 | } 102 | 103 | /** 104 | * @return $this 105 | */ 106 | public function type(string $type): static 107 | { 108 | $this->type = $type; 109 | 110 | return $this; 111 | } 112 | 113 | public function request(?int $taxFreeAmount = null): PromiseInterface|Response 114 | { 115 | $parameters = []; 116 | if ($taxFreeAmount) { 117 | $parameters['taxFreeAmount'] = $taxFreeAmount; 118 | } 119 | 120 | return $this->client->post($this->createEndpoint('/'), [ 121 | 'amount' => $this->amount, 122 | 'orderId' => $this->orderId, 123 | 'orderName' => $this->orderName, 124 | 'customerIdentityNumber' => $this->customerIdentityNumber, 125 | 'type' => $this->type, 126 | ] + $parameters); 127 | } 128 | 129 | public function cancel(?int $amount = null): PromiseInterface|Response 130 | { 131 | $parameters = []; 132 | if ($amount) { 133 | $parameters['amount'] = $amount; 134 | } 135 | 136 | return $this->client->post($this->createEndpoint('/'.$this->receiptKey.'/cancel'), $parameters); 137 | } 138 | 139 | /** 140 | * @return $this 141 | */ 142 | public function requestDate(string $requestDate): static 143 | { 144 | $this->requestDate = $requestDate; 145 | 146 | return $this; 147 | } 148 | 149 | public function get(?int $cursor = null, ?int $limit = null): PromiseInterface|Response 150 | { 151 | $parameters = []; 152 | if ($cursor) { 153 | $parameters['cursor'] = $cursor; 154 | } 155 | 156 | if ($limit) { 157 | $parameters['limit'] = $limit; 158 | } 159 | 160 | return $this->client->get($this->createEndpoint('/'), [ 161 | 'requestDate' => $this->requestDate, 162 | ] + $parameters); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A Laravel package to Toss Payments 2 | 3 | 4 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/getsolaris/laravel-tosspayments.svg?style=flat-square)](https://packagist.org/packages/getsolaris/laravel-tosspayments) 5 | [![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/getsolaris/laravel-tosspayments/run-tests?label=tests)](https://github.com/getsolaris/laravel-tosspayments/actions?query=workflow%3Arun-tests+branch%3Amain) 6 | [![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/getsolaris/laravel-tosspayments/Fix%20PHP%20code%20style%20issues?label=code%20style)](https://github.com/getsolaris/laravel-tosspayments/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain) 7 | 8 | 9 | 토스페이먼츠 (Toss Payments) 라라벨 API 입니다. 10 | 11 | ### API 버전: 2022-11-16 12 | [API 버전 정책](https://docs.tosspayments.com/reference/versioning#%EB%82%B4-%EC%83%81%EC%A0%90%EC%9D%98-api-%EB%B2%84%EC%A0%84-%ED%99%95%EC%9D%B8%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0) 13 | 14 | | Version | API Version | 15 | |---------|-------------| 16 | | v1.2 | 2022-11-16 | 17 | | v1.1 | 2022-07-27 | 18 | 19 | --- 20 | 21 | # 설치 22 | ```bash 23 | composer require getsolaris/laravel-tosspayments 24 | ``` 25 | 26 | `.env` 에 아래의 환경변수가 추가되어야 합니다. 27 | Toss Payments 개발자센터에서 발급받은 클라이언트 키와 시크릿 키를 환경변수에 추가합니다. 28 | 29 | ```bash 30 | TOSS_PAYMENTS_CLIENT_KEY= 31 | TOSS_PAYMENTS_SECRET_KEY= 32 | ``` 33 | 34 | `config` 파일을 생성하기 위해서 아래 명령어를 수행합니다. 35 | 36 | ```bash 37 | php artisan vendor:publish --provider="Getsolaris\LaravelTossPayments\TossPaymentsServiceProvider" --tag="config" 38 | ``` 39 | 40 | # 사용 41 | 42 | Toss Payments 개발자센터의 [코어 API](https://docs.tosspayments.com/reference) 를 참고합니다. 43 | 44 | API 를 사용하기 앞서 인증을 위한 API 키 준비와 인증 관련된 문서는 [해당 페이지](https://docs.tosspayments.com/guides/using-api)에서 확인 가능합니다. 45 | 46 | Basic 인증 방식은 `{SECRET_KEY}:` 를 Base64 인코딩 한 값을 사용합니다. 47 | 48 | 49 | 50 | ## [결제 (Payment)](https://docs.tosspayments.com/reference#%EA%B2%B0%EC%A0%9C) 51 | 52 | [예제 보기](examples/PAYMENT.md) 53 | 54 | 55 | ## [거래 (Transaction)](https://docs.tosspayments.com/reference#%EA%B1%B0%EB%9E%98) 56 | 57 | [예제 보기](examples/TRANSACTION.md) 58 | 59 | 60 | ## [자동 결제 (Billing)](https://docs.tosspayments.com/reference#%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C) 61 | 62 | [예제 보기](examples/BILLING.md) 63 | 64 | 65 | ## [정산 (Settlement)](https://docs.tosspayments.com/reference#%EC%A0%95%EC%82%B0) 66 | 67 | [예제 보기](examples/SETTLEMENT.md) 68 | 69 | 70 | ## [현금영수증 (CashReceipt)](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D) 71 | 72 | [예제 보기](examples/CASHRECEIPT.md) 73 | 74 | 75 | ## [카드사 혜택 조회 (Promotion)](https://docs.tosspayments.com/reference#%EC%B9%B4%EB%93%9C%EC%82%AC-%ED%98%9C%ED%83%9D-%EC%A1%B0%ED%9A%8C) 76 | 77 | [예제 보기](examples/PROMOTION.md) 78 | 79 | ## [웹훅 (Webhook) 연동하기](https://docs.tosspayments.com/guides/webhook#%EC%9B%B9%ED%9B%85webhook-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0) 80 | 81 | 웹훅을 사용하기 전에 토스페이먼츠 개발자센터 웹훅 페이지에서 웹훅을 등록해주세요. 82 | 83 | 웹훅을 이용하기 전에 `config/tosspayments.php` 파일에서 `webhook` 설정을 확인해주세요. 84 | 85 | ``` 86 | 'webhook' => [ 87 | 'handler' => [ 88 | 'controller' => \App\Http\Controllers\WebhookController::class, 89 | 'method' => '__invoke', 90 | ], 91 | ], 92 | ``` 93 | 94 | `handler` 설정을 변경하여 웹훅을 처리할 컨트롤러와 메소드를 지정할 수 있습니다. 95 | 96 | 또한 아래의 명령어를 실행하여 기본 라우트 설정값인 `url/webhooks/tosspayments` 를 변경할 수 있습니다. 97 | 98 | ```bash 99 | php artisan vendor:publish --provider="Getsolaris\LaravelTossPayments\TossPaymentsServiceProvider" --tag="webhook" 100 | ``` 101 | 102 | 103 | ## [테스트 코드 사용하기](https://docs.tosspayments.com/reference/error-codes#%EC%97%90%EB%9F%AC-%EC%BD%94%EB%93%9C) 104 | 105 | [에러코드](https://docs.tosspayments.com/reference/error-codes#%EC%97%90%EB%9F%AC-%EC%BD%94%EB%93%9C)를 확인하여 106 | 특정 에러가 발생했을 때와 같이 예상된 시나리오를 직접 발생시켜 처리해 볼 수 있습니다. 107 | 108 | ```php 109 | use Getsolaris\LaravelTossPayments\TossPayments; 110 | use Getsolaris\LaravelTossPayments\Attributes\Transaction; 111 | 112 | $transactions = TossPayments::for(Transaction::class) 113 | ->startDate('2022-01-01T00:00:00') 114 | ->endDate('2022-12-31T00:00:00') 115 | ->testCode('INVALID_CARD_EXPIRATION') 116 | ->get(); 117 | ``` 118 | 119 | 120 | ## Resource 121 | - [Toss Payments 개발자센터](https://developers.tosspayments.com/) 122 | - [Toss Payments 코어 API](https://docs.tosspayments.com/reference) 123 | 124 | ## Changelog 125 | 126 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 127 | 128 | ## License 129 | 130 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 131 | -------------------------------------------------------------------------------- /src/Attributes/Billing.php: -------------------------------------------------------------------------------- 1 | initializeUri(); 39 | } 40 | 41 | /** 42 | * @return $this 43 | */ 44 | public function initializeUri(): static 45 | { 46 | $this->uri = '/billing'; 47 | 48 | return $this; 49 | } 50 | 51 | public function createEndpoint(?string $endpoint, bool $withUri = true): string 52 | { 53 | if ($withUri) { 54 | return $this->url.$this->uri.$this->start($endpoint); 55 | } 56 | 57 | return $this->url.$this->start($endpoint); 58 | } 59 | 60 | /** 61 | * @return $this 62 | */ 63 | public function customerKey(string $customerKey): static 64 | { 65 | $this->customerKey = $customerKey; 66 | 67 | return $this; 68 | } 69 | 70 | /** 71 | * @return $this 72 | */ 73 | public function cardNumber(string $cardNumber): static 74 | { 75 | $this->cardNumber = $cardNumber; 76 | 77 | return $this; 78 | } 79 | 80 | /** 81 | * @return $this 82 | */ 83 | public function cardExpirationYear(string $cardExpirationYear): static 84 | { 85 | $this->cardExpirationYear = $cardExpirationYear; 86 | 87 | return $this; 88 | } 89 | 90 | /** 91 | * @return $this 92 | */ 93 | public function cardExpirationMonth(string $cardExpirationMonth): static 94 | { 95 | $this->cardExpirationMonth = $cardExpirationMonth; 96 | 97 | return $this; 98 | } 99 | 100 | /** 101 | * @return $this 102 | */ 103 | public function customerIdentityNumber(string $customerIdentityNumber) 104 | { 105 | $this->customerIdentityNumber = $customerIdentityNumber; 106 | 107 | return $this; 108 | } 109 | 110 | public function authorizationsCard( 111 | ?string $cardPassword = null, 112 | ?string $customerName = null, 113 | ?string $customerEmail = null, 114 | ?Vbv $vbv = null 115 | ): PromiseInterface|Response { 116 | $parameters = []; 117 | if ($cardPassword) { 118 | $parameters['cardPassword'] = $cardPassword; 119 | } 120 | 121 | if ($customerName) { 122 | $parameters['customerName'] = $customerName; 123 | } 124 | 125 | if ($customerEmail) { 126 | $parameters['customerEmail'] = $customerEmail; 127 | } 128 | 129 | if ($vbv) { 130 | $parameters['vbv'] = (array) $vbv; 131 | } 132 | 133 | return $this->client->post($this->createEndpoint('/authorizations/card'), [ 134 | 'customerKey' => $this->customerKey, 135 | 'cardNumber' => $this->cardNumber, 136 | 'cardExpirationYear' => $this->cardExpirationYear, 137 | 'cardExpirationMonth' => $this->cardExpirationMonth, 138 | 'customerIdentityNumber' => $this->customerIdentityNumber, 139 | ] + $parameters); 140 | } 141 | 142 | public function authorizationsIssue(): PromiseInterface|Response 143 | { 144 | return $this->client->post($this->createEndpoint('/authorizations/issue'), [ 145 | 'authKey' => $this->authKey, 146 | 'customerKey' => $this->customerKey, 147 | ]); 148 | } 149 | 150 | /** 151 | * @return $this 152 | */ 153 | public function billingKey(string $billingKey): static 154 | { 155 | $this->billingKey = $billingKey; 156 | 157 | return $this; 158 | } 159 | 160 | public function amount(int $amount): static 161 | { 162 | $this->amount = $amount; 163 | 164 | return $this; 165 | } 166 | 167 | public function orderId(string $orderId): static 168 | { 169 | $this->orderId = $orderId; 170 | 171 | return $this; 172 | } 173 | 174 | public function orderName(string $orderName): static 175 | { 176 | $this->orderName = $orderName; 177 | 178 | return $this; 179 | } 180 | 181 | public function request( 182 | ?string $customerEmail = null, 183 | ?string $customerName = null, 184 | ?string $customerMobilePhone = null, 185 | ?int $taxFreeAmount = null, 186 | ?int $cardInstallmentPlan = null 187 | ): PromiseInterface|Response { 188 | $parameters = []; 189 | if ($customerEmail) { 190 | $parameters['customerEmail'] = $customerEmail; 191 | } 192 | 193 | if ($customerName) { 194 | $parameters['customerName'] = $customerName; 195 | } 196 | 197 | if ($customerMobilePhone) { 198 | $parameters['customerMobilePhone'] = $customerMobilePhone; 199 | } 200 | 201 | if ($taxFreeAmount) { 202 | $parameters['taxFreeAmount'] = $taxFreeAmount; 203 | } 204 | 205 | if ($cardInstallmentPlan) { 206 | $parameters['cardInstallmentPlan'] = $cardInstallmentPlan; 207 | } 208 | 209 | return $this->client->post($this->createEndpoint('/'.$this->billingKey), [ 210 | 'amount' => $this->amount, 211 | 'customerKey' => $this->customerKey, 212 | 'orderId' => $this->orderId, 213 | 'orderName' => $this->orderName, 214 | ] + $parameters); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/Attributes/Payment.php: -------------------------------------------------------------------------------- 1 | initializeUri(); 43 | } 44 | 45 | /** 46 | * @return $this 47 | */ 48 | public function initializeUri(): static 49 | { 50 | $this->uri = '/payments'; 51 | 52 | return $this; 53 | } 54 | 55 | public function createEndpoint(?string $endpoint, bool $withUri = true): string 56 | { 57 | if ($withUri) { 58 | return $this->url.$this->uri.$this->start($endpoint); 59 | } 60 | 61 | return $this->url.$this->start($endpoint); 62 | } 63 | 64 | /** 65 | * @return $this 66 | */ 67 | public function paymentKey(string $paymentKey): static 68 | { 69 | $this->paymentKey = $paymentKey; 70 | 71 | return $this; 72 | } 73 | 74 | /** 75 | * @return $this 76 | */ 77 | public function orderId(string $orderId): static 78 | { 79 | $this->orderId = $orderId; 80 | 81 | return $this; 82 | } 83 | 84 | /** 85 | * @return $this 86 | */ 87 | public function amount(int $amount): static 88 | { 89 | $this->amount = $amount; 90 | 91 | return $this; 92 | } 93 | 94 | public function confirm(): PromiseInterface|Response 95 | { 96 | return $this->client->post($this->createEndpoint('/confirm'), [ 97 | 'paymentKey' => $this->paymentKey, 98 | 'orderId' => $this->orderId, 99 | 'amount' => $this->amount, 100 | ]); 101 | } 102 | 103 | public function get(): PromiseInterface|Response 104 | { 105 | return $this->client->get($this->createEndpoint('/'.($this->paymentKey ?? 'orders/'.$this->orderId))); 106 | } 107 | 108 | /** 109 | * @return $this 110 | */ 111 | public function cancelReason(string $cancelReason): static 112 | { 113 | $this->cancelReason = $cancelReason; 114 | 115 | return $this; 116 | } 117 | 118 | public function cancel( 119 | ?int $cancelAmount = null, 120 | ?RefundReceiveAccount $refundReceiveAccount = null, 121 | ?int $taxFreeAmount = null, 122 | ?int $refundableAmount = null 123 | ): PromiseInterface|Response { 124 | $parameters = []; 125 | if ($cancelAmount) { 126 | $parameters['cancelAmount'] = $cancelAmount; 127 | } 128 | 129 | if ($refundReceiveAccount) { 130 | $parameters['refundReceiveAccount'] = (array) $refundReceiveAccount; 131 | } 132 | 133 | if ($taxFreeAmount) { 134 | $parameters['taxFreeAmount'] = $taxFreeAmount; 135 | } 136 | 137 | if ($refundableAmount) { 138 | $parameters['refundableAmount'] = $refundableAmount; 139 | } 140 | 141 | return $this->client->post($this->createEndpoint('/'.$this->paymentKey.'/cancel'), [ 142 | 'cancelReason' => $this->cancelReason, 143 | ] + $parameters); 144 | } 145 | 146 | /** 147 | * @return $this 148 | */ 149 | public function orderName(string $orderName): static 150 | { 151 | $this->orderName = $orderName; 152 | 153 | return $this; 154 | } 155 | 156 | /** 157 | * @return $this 158 | */ 159 | public function customerName(string $customerName): static 160 | { 161 | $this->customerName = $customerName; 162 | 163 | return $this; 164 | } 165 | 166 | /** 167 | * @return $this 168 | */ 169 | public function bank(string $bank): static 170 | { 171 | $this->bank = $bank; 172 | 173 | return $this; 174 | } 175 | 176 | public function virtualAccounts( 177 | ?string $accountType = null, 178 | ?string $accountKey = null, 179 | ?int $validHours = null, 180 | ?string $dueDate = null, 181 | ?string $customerEmail = null, 182 | ?string $customerMobilePhone = null, 183 | ?int $taxFreeAmount = null, 184 | ?bool $useEscrow = null, 185 | ?CashReceipt $cashReceipt = null, 186 | ?array $escrowProducts = null 187 | ): PromiseInterface|Response { 188 | $parameters = []; 189 | if ($accountType) { 190 | $parameters['accountType'] = $accountType; 191 | } 192 | 193 | if ($accountKey) { 194 | $parameters['accountKey'] = $accountKey; 195 | } 196 | 197 | if ($validHours) { 198 | $parameters['validHours'] = $validHours; 199 | } 200 | 201 | if ($dueDate) { 202 | $parameters['dueDate'] = $dueDate; 203 | } 204 | 205 | if ($customerEmail) { 206 | $parameters['customerEmail'] = $customerEmail; 207 | } 208 | 209 | if ($customerMobilePhone) { 210 | $parameters['customerMobilePhone'] = $customerMobilePhone; 211 | } 212 | 213 | if ($taxFreeAmount) { 214 | $parameters['taxFreeAmount'] = $taxFreeAmount; 215 | } 216 | 217 | if ($useEscrow) { 218 | $parameters['useEscrow'] = $useEscrow; 219 | } 220 | 221 | if ($cashReceipt) { 222 | $parameters['cashReceipt'] = (array) $cashReceipt; 223 | } 224 | 225 | if ($escrowProducts) { 226 | $parameters['escrowProducts'] = $escrowProducts; 227 | } 228 | 229 | return $this->client->post($this->createEndpoint('/virtual-accounts', false), [ 230 | 'amount' => $this->amount, 231 | 'orderId' => $this->orderId, 232 | 'orderName' => $this->orderName, 233 | 'customerName' => $this->customerName, 234 | 'bank' => $this->bank, 235 | ] + $parameters); 236 | } 237 | 238 | /** 239 | * @return $this 240 | */ 241 | public function cardNumber(string $cardNumber): static 242 | { 243 | $this->cardNumber = $cardNumber; 244 | 245 | return $this; 246 | } 247 | 248 | /** 249 | * @return $this 250 | */ 251 | public function cardExpirationYear(string $cardExpirationYear): static 252 | { 253 | $this->cardExpirationYear = $cardExpirationYear; 254 | 255 | return $this; 256 | } 257 | 258 | /** 259 | * @return $this 260 | */ 261 | public function cardExpirationMonth(string $cardExpirationMonth): static 262 | { 263 | $this->cardExpirationMonth = $cardExpirationMonth; 264 | 265 | return $this; 266 | } 267 | 268 | /** 269 | * @return $this 270 | */ 271 | public function customerIdentityNumber(string $customerIdentityNumber) 272 | { 273 | $this->customerIdentityNumber = $customerIdentityNumber; 274 | 275 | return $this; 276 | } 277 | 278 | public function keyIn( 279 | ?string $cardPassword = null, 280 | ?int $cardInstallmentPlan = null, 281 | ?bool $useFreeInstallmentPlan = null, 282 | ?int $taxFreeAmount = null, 283 | ?string $customerEmail = null, 284 | ?string $customerName = null, 285 | ?Vbv $vbv = null 286 | ): PromiseInterface|Response { 287 | $parameters = []; 288 | if ($cardPassword) { 289 | $parameters['cardPassword'] = $cardPassword; 290 | } 291 | 292 | if ($cardInstallmentPlan) { 293 | $parameters['cardInstallmentPlan'] = $cardInstallmentPlan; 294 | } 295 | 296 | if ($useFreeInstallmentPlan) { 297 | $parameters['useFreeInstallmentPlan'] = $useFreeInstallmentPlan; 298 | } 299 | 300 | if ($taxFreeAmount) { 301 | $parameters['taxFreeAmount'] = $taxFreeAmount; 302 | } 303 | 304 | if ($customerEmail) { 305 | $parameters['customerEmail'] = $customerEmail; 306 | } 307 | 308 | if ($customerName) { 309 | $parameters['customerName'] = $customerName; 310 | } 311 | 312 | if ($vbv) { 313 | $parameters['vbv'] = (array) $vbv; 314 | } 315 | 316 | return $this->client->post($this->createEndpoint('/key-in'), [ 317 | 'amount' => $this->amount, 318 | 'orderId' => $this->orderId, 319 | 'orderName' => $this->orderName, 320 | 'cardNumber' => $this->cardNumber, 321 | 'cardExpirationYear' => $this->cardExpirationYear, 322 | 'cardExpirationMonth' => $this->cardExpirationMonth, 323 | 'customerIdentityNumber' => $this->customerIdentityNumber, 324 | ] + $parameters); 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to laravel-tosspayments will be documented in this file. 4 | 5 | ## Laravel Toss Payments v1.3.3 - 2025-03-02 6 | 7 | ### What's Changed 8 | 9 | * support laravel 12 by @brez-dev in https://github.com/getsolaris/laravel-tosspayments/pull/14 10 | 11 | ### New Contributors 12 | 13 | * @brez-dev made their first contribution in https://github.com/getsolaris/laravel-tosspayments/pull/14 14 | 15 | **Full Changelog**: https://github.com/getsolaris/laravel-tosspayments/compare/v1.3.2...v1.3.3 16 | 17 | ## v.1.3.2 - 2024-09-04 18 | 19 | Laravel 11 지원 20 | 21 | ## v1.3.1 - 2024-01-15 22 | 23 | ### Laravel Toss Payments v1.3.1 24 | 25 | - Laravel 10 지원 26 | 27 | ## v1.3 - 2022-12-11 28 | 29 | ### Laravel Toss Payments v1.3 30 | 31 | - config 파일명이 `toss-payments.php` 에서 `tosspayments.php` 로 변경되었습니다. 32 | 33 | #### [웹훅 (Webhook) 연동하기](https://docs.tosspayments.com/guides/webhook#%EC%9B%B9%ED%9B%85webhook-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0) 34 | 35 | 웹훅을 사용하기 전에 토스페이먼츠 개발자센터 웹훅 페이지에서 웹훅을 등록해주세요. 36 | 37 | 웹훅을 이용하기 전에 `config/tosspayments.php` 파일에서 `webhook` 설정을 확인해주세요. 38 | 39 | ``` 40 | 'webhook' => [ 41 | 'handler' => [ 42 | 'controller' => \App\Http\Controllers\WebhookController::class, 43 | 'method' => '__invoke', 44 | ], 45 | ], 46 | 47 | 48 | 49 | 50 | ``` 51 | `handler` 설정을 변경하여 웹훅을 처리할 컨트롤러와 메소드를 지정할 수 있습니다. 52 | 53 | 또한 아래의 명령어를 실행하여 기본 라우트 설정값인 `url/webhooks/tosspayments` 를 변경할 수 있습니다. 54 | 55 | ```bash 56 | php artisan vendor:publish --provider="Getsolaris\LaravelTossPayments\TossPaymentsServiceProvider" --tag="webhook" 57 | 58 | 59 | 60 | 61 | ``` 62 | ## v1.2 - 2022-12-05 63 | 64 | ### Laravel Toss Payments v1.2 65 | 66 | 토스페이먼츠 API `2022-11-16` 릴리즈로 큰 변화는 생기지 않았지만, 편의를 위해서 아래의 기능이 추가 되었습니다. 67 | 68 | #### [숫자 기관 코드 사용](https://docs.tosspayments.com/reference/release-note#2022-11-16) 69 | 70 | > 한글 영문 기관 코드를 [숫자 기관 코드](https://docs.tosspayments.com/reference/codes)로 대체합니다. 응답은 숫자 코드만 지원합니다. 요청은 숫자 한글 영문 코드를 지원하지만 숫자 코드 사용을 권장합니다. (토스페이먼츠 본문) 71 | 72 | - 숫자 코드 73 | - 한글 (kr) 코드 -> 숫자 코드 (code) 74 | - 영문 (en) 코드 -> 숫자 코드 (code) 75 | 76 | 한글과 영문 코드는 [숫자 기관 코드](https://docs.tosspayments.com/reference/codes) 에서 명시된 코드만 지원합니다. 77 | 78 | ```php 79 | assertSame(self::TEST_TOSSBANK_CODE, $code); 103 | } 104 | 105 | /** 106 | * 영문으로 입력된 경우 코드로 변환 107 | * 108 | * @return void 109 | * 110 | * @throws InvalidInputTargetCodeException 111 | * @throws \ReflectionException 112 | */ 113 | public function testConvertEnToCode(): void 114 | { 115 | $code = BankCode::toCode('TOSSBANK'); 116 | $this->assertSame(self::TEST_TOSSBANK_CODE, $code); 117 | } 118 | 119 | /** 120 | * 코드로 입력된 경우 올바른 코드인지 확인 후 반환 121 | * 122 | * @return void 123 | * 124 | * @throws InvalidInputTargetCodeException 125 | * @throws \ReflectionException 126 | */ 127 | public function testAlwaysCode(): void 128 | { 129 | $code = BankCode::toCode(self::TEST_TOSSBANK_CODE); 130 | $this->assertSame(self::TEST_TOSSBANK_CODE, $code); 131 | } 132 | 133 | /** 134 | * 올바르지 않은 코드가 입력된 경우 예외처리 발생 135 | * 136 | * @return void 137 | * 138 | * @throws InvalidInputTargetCodeException 139 | * @throws \ReflectionException 140 | */ 141 | public function testInvalidInputTargetCodeException(): void 142 | { 143 | $this->expectException(InvalidInputTargetCodeException::class); 144 | BankCode::toCode('invalid'); 145 | } 146 | } 147 | 148 | 149 | 150 | 151 | 152 | 153 | ``` 154 | 기관 코드 변환을 지원하는 코드는 아래와 같습니다. 155 | 156 | - 카드사 코드 157 | 158 | - - 국내 159 | 160 | - 161 | - - 해외 162 | 163 | - 164 | - 165 | - 은행 코드 166 | 167 | 168 | **Full Changelog**: https://github.com/getsolaris/laravel-tosspayments/compare/v1.1...v1.2 169 | 170 | ## v1.1 - 2022-11-06 171 | 172 | ### Laravel Toss Payments v1.1 173 | 174 | #### [자동 결제 (Billing)](https://docs.tosspayments.com/reference#%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C) 175 | 176 | ##### [customerKey로 카드 자동 결제 빌링키 발급 요청](https://docs.tosspayments.com/reference#customerkey%EB%A1%9C-%EC%B9%B4%EB%93%9C-%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C-%EB%B9%8C%EB%A7%81%ED%82%A4-%EB%B0%9C%EA%B8%89-%EC%9A%94%EC%B2%AD) 177 | 178 | POST /v1/billing/authorizations/card 179 | 180 | ```php 181 | use Getsolaris\LaravelTossPayments\TossPayments; 182 | use Getsolaris\LaravelTossPayments\Attributes\Billing; 183 | 184 | $billing = TossPayments::for(Billing::class) 185 | ->customerKey($customerKey) 186 | ->cardNumber($cardNumber) 187 | ->cardExpirationYear($cardExpirationYear) 188 | ->cardExpirationMonth($cardExpirationMonth) 189 | ->customerIdentityNumber($customerIdentityNumber) 190 | ->authorizationsCard(); 191 | 192 | return $billing->json(); 193 | 194 | 195 | 196 | 197 | 198 | 199 | ``` 200 | ##### [authKey로 카드 자동 결제 빌링키 발급 요청](https://docs.tosspayments.com/reference#authkey%EB%A1%9C-%EC%B9%B4%EB%93%9C-%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C-%EB%B9%8C%EB%A7%81%ED%82%A4-%EB%B0%9C%EA%B8%89-%EC%9A%94%EC%B2%AD) 201 | 202 | POST /v1/billing/authorizations/issue 203 | 204 | ```php 205 | use Getsolaris\LaravelTossPayments\TossPayments; 206 | use Getsolaris\LaravelTossPayments\Attributes\Billing; 207 | 208 | $billing = TossPayments::for(Billing::class) 209 | ->customerKey($customerKey) 210 | ->authKey($authKey) 211 | ->authorizationsIssue(); 212 | 213 | return $billing->json(); 214 | 215 | 216 | 217 | 218 | 219 | 220 | ``` 221 | ##### [카드 자동 결제 승인 요청](https://docs.tosspayments.com/reference#%EC%B9%B4%EB%93%9C-%EC%9E%90%EB%8F%99-%EA%B2%B0%EC%A0%9C-%EC%8A%B9%EC%9D%B8-%EC%9A%94%EC%B2%AD) 222 | 223 | POST /v1/billing/{billingKey} 224 | 225 | ```php 226 | use Getsolaris\LaravelTossPayments\TossPayments; 227 | use Getsolaris\LaravelTossPayments\Attributes\Billing; 228 | 229 | $billing = TossPayments::for(Billing::class) 230 | ->customerKey($customerKey) 231 | ->authKey($authKey) 232 | ->authorizationsIssue(); 233 | 234 | return $billing->json(); 235 | 236 | 237 | 238 | 239 | 240 | 241 | ``` 242 | #### [정산 (Settlement)](https://docs.tosspayments.com/reference#%EC%A0%95%EC%82%B0) 243 | 244 | ##### [정산 조회](https://docs.tosspayments.com/reference#%EC%A0%95%EC%82%B0-%EC%A1%B0%ED%9A%8C) 245 | 246 | GET /v1/settlements 247 | 248 | ```php 249 | use Getsolaris\LaravelTossPayments\TossPayments; 250 | use Getsolaris\LaravelTossPayments\Attributes\Settlement; 251 | 252 | $settlements = TossPayments::for(Settlement::class) 253 | ->startDate($startDate) 254 | ->endDate($endDate) 255 | ->get(); 256 | 257 | return $settlements->json(); 258 | 259 | 260 | 261 | 262 | 263 | 264 | ``` 265 | ##### [수동 정산 요청](https://docs.tosspayments.com/reference#%EC%88%98%EB%8F%99-%EC%A0%95%EC%82%B0-%EC%9A%94%EC%B2%AD) 266 | 267 | POST /v1/settlements 268 | 269 | ```php 270 | use Getsolaris\LaravelTossPayments\TossPayments; 271 | use Getsolaris\LaravelTossPayments\Attributes\Settlement; 272 | 273 | $settlement = TossPayments::for(Settlement::class) 274 | ->paymentKey($paymentKey) 275 | ->request(); 276 | 277 | return $settlement->json(); 278 | 279 | 280 | 281 | 282 | 283 | 284 | ``` 285 | #### [현금영수증 (CashReceipt)](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D) 286 | 287 | ##### [현금영수증 발급](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D) 288 | 289 | POST /v1/cash-receipts 290 | 291 | ```php 292 | use Getsolaris\LaravelTossPayments\TossPayments; 293 | use Getsolaris\LaravelTossPayments\Attributes\CashReceipt; 294 | 295 | $cashReceipt = TossPayments::for(CashReceipt::class) 296 | ->amount($amount) 297 | ->orderId($orderId) 298 | ->orderName($orderName) 299 | ->customerIdentityNumber($customerIdentityNumber) 300 | ->type($type) 301 | ->request(); 302 | 303 | return $cashReceipt->json(); 304 | 305 | 306 | 307 | 308 | 309 | 310 | ``` 311 | ##### [현금영수증 발급 취소](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D-%EB%B0%9C%EA%B8%89-%EC%B7%A8%EC%86%8C) 312 | 313 | POST /v1/cash-receipts/{receiptKey}/cancel 314 | 315 | ```php 316 | use Getsolaris\LaravelTossPayments\TossPayments; 317 | use Getsolaris\LaravelTossPayments\Attributes\CashReceipt; 318 | 319 | $cashReceipt = TossPayments::for(CashReceipt::class) 320 | ->receiptKey($receiptKey) 321 | ->cancel(); 322 | 323 | return $cashReceipt->json(); 324 | 325 | 326 | 327 | 328 | 329 | 330 | ``` 331 | ##### [현금영수증 조회](https://docs.tosspayments.com/reference#%ED%98%84%EA%B8%88%EC%98%81%EC%88%98%EC%A6%9D-%EC%A1%B0%ED%9A%8C) 332 | 333 | GET /v1/cash-receipts 334 | 335 | ```php 336 | use Getsolaris\LaravelTossPayments\TossPayments; 337 | use Getsolaris\LaravelTossPayments\Attributes\CashReceipt; 338 | 339 | $cashReceipts = TossPayments::for(CashReceipt::class) 340 | ->requestDate($requestDate) 341 | ->get(); 342 | 343 | return $cashReceipts->json(); 344 | 345 | 346 | 347 | 348 | 349 | 350 | ``` 351 | #### [카드사 혜택 조회 (CardPromotion)](https://docs.tosspayments.com/reference#%EC%B9%B4%EB%93%9C%EC%82%AC-%ED%98%9C%ED%83%9D-%EC%A1%B0%ED%9A%8C) 352 | 353 | ##### [카드사 혜택 조회](https://docs.tosspayments.com/reference#%EC%B9%B4%EB%93%9C%EC%82%AC-%ED%98%9C%ED%83%9D-%EC%A1%B0%ED%9A%8C-1) 354 | 355 | GET /v1/promotions/card 356 | 357 | ```php 358 | use Getsolaris\LaravelTossPayments\TossPayments; 359 | use Getsolaris\LaravelTossPayments\Attributes\Promotion; 360 | 361 | $promotions = TossPayments::for(Promotion::class) 362 | ->get(); 363 | 364 | return $promotions->json(); 365 | 366 | 367 | 368 | 369 | 370 | 371 | ``` 372 | **Full Changelog**: https://github.com/getsolaris/laravel-tosspayments/compare/v1.0.2...v1.1 373 | 374 | ## v1.0.2 - 2022-11-04 375 | 376 | ### Laravel Toss Payments v1.0.2 377 | 378 | - 카드 번호 결제 379 | 380 | ```php 381 | use Getsolaris\LaravelTossPayments\TossPayments; 382 | use Getsolaris\LaravelTossPayments\Attributes\Payment; 383 | 384 | $keyIn = TossPayments::for(Payment::class) 385 | ->amount($amount) 386 | ->orderId($orderId) 387 | ->orderName($orderName) 388 | ->cardNumber($cardNumber) 389 | ->cardExpirationYear($cardExpirationYear) 390 | ->cardExpirationMonth($cardExpirationMonth) 391 | ->customerIdentityNumber($customerIdentityNumber) 392 | ->keyIn(); 393 | 394 | return $keyIn->json(); 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | ``` 403 | - 가상계좌 발급 요청 404 | 405 | ```php 406 | use Getsolaris\LaravelTossPayments\TossPayments; 407 | use Getsolaris\LaravelTossPayments\Attributes\Payment; 408 | 409 | $virtualAccounts = TossPayments::for(Payment::class) 410 | ->amount($amount) 411 | ->orderId($orderId) 412 | ->orderName($orderName) 413 | ->customerName($customerName) 414 | ->bank('우리') 415 | ->virtualAccounts(); 416 | 417 | return $virtualAccounts->json(); 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | ``` 426 | **Full Changelog**: https://github.com/getsolaris/laravel-tosspayments/compare/v1.0.1...v1.0.2 427 | 428 | ## v1.0.1 - 2022-11-02 429 | 430 | ### Laravel Toss Payments v1.0.1 431 | 432 | - 결제 조회 433 | 434 | - - `paymentId`로 결제 조회 435 | 436 | - 437 | - 438 | - 439 | - 440 | - - `orderId`로 결제 조회 441 | 442 | - 443 | - 444 | - 445 | - 446 | - 447 | - 결제 취소 448 | 449 | 450 | **Full Changelog**: https://github.com/getsolaris/laravel-tosspayments/compare/v1.0...v1.0.1 451 | --------------------------------------------------------------------------------