Skip to content

Commit

Permalink
inital commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vamsii777 committed Feb 15, 2024
0 parents commit 0ed08b1
Show file tree
Hide file tree
Showing 34 changed files with 2,263 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT LICENSE

Copyright (c) 2024 Vamsi Madduluri

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:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

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.
131 changes: 131 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
{
"pins" : [
{
"identity" : "async-http-client",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/async-http-client.git",
"state" : {
"revision" : "291438696abdd48d2a83b52465c176efbd94512b",
"version" : "1.20.1"
}
},
{
"identity" : "swift-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-algorithms",
"state" : {
"revision" : "f6919dfc309e7f1b56224378b11e28bab5bccc42",
"version" : "1.2.0"
}
},
{
"identity" : "swift-atomics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-atomics.git",
"state" : {
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
"version" : "1.2.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb",
"version" : "1.1.0"
}
},
{
"identity" : "swift-crypto",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-crypto.git",
"state" : {
"revision" : "cc76b894169a3c86b71bac10c78a4db6beb7a9ad",
"version" : "3.2.0"
}
},
{
"identity" : "swift-http-types",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-types",
"state" : {
"revision" : "12358d55a3824bd5fed310b999ea8cf83a9a1a65",
"version" : "1.0.3"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log.git",
"state" : {
"revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5",
"version" : "1.5.4"
}
},
{
"identity" : "swift-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "635b2589494c97e48c62514bc8b37ced762e0a62",
"version" : "2.63.0"
}
},
{
"identity" : "swift-nio-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
"revision" : "363da63c1966405764f380c627409b2f9d9e710b",
"version" : "1.21.0"
}
},
{
"identity" : "swift-nio-http2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "0904bf0feb5122b7e5c3f15db7df0eabe623dd87",
"version" : "1.30.0"
}
},
{
"identity" : "swift-nio-ssl",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-ssl.git",
"state" : {
"revision" : "7c381eb6083542b124a6c18fae742f55001dc2b5",
"version" : "2.26.0"
}
},
{
"identity" : "swift-nio-transport-services",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"state" : {
"revision" : "6cbe0ed2b394f21ab0d46b9f0c50c6be964968ce",
"version" : "1.20.1"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-numerics.git",
"state" : {
"revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
"version" : "1.0.2"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "025bcb1165deab2e20d4eaba79967ce73013f496",
"version" : "1.2.1"
}
}
],
"version" : 2
}
27 changes: 27 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "RazorpayKit",
platforms: [
.macOS(.v13)
],
products: [.library(name: "RazorpayKit", targets: ["RazorpayKit"])],
dependencies: [
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.20.1"),
.package(url: "https://github.com/apple/swift-crypto.git", from: "3.1.0")
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(name: "RazorpayKit", dependencies: [
.product(name: "AsyncHTTPClient", package: "async-http-client"),
.product(name: "Crypto", package: "swift-crypto"),
]),
.testTarget(
name: "RazorpayKitTests",
dependencies: ["RazorpayKit"]),
]
)
97 changes: 97 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# RazorpayKit
![](https://img.shields.io/badge/Swift-5.9-green.svg?style=svg)
![](https://img.shields.io/badge/SwiftNio-2-orange.svg?style=svg)

RazorpayKit is a Swift library for integrating with Razorpay's payment gateway. It supports managing orders, payments, subscriptions, webhooks and more.

## Installation

### Swift Package Manager

You can add RazorpayKit to your project via Swift Package Manager (SPM) by adding the following dependency to your `Package.swift` file:

```swift
dependencies: [
.package(url: "https://github.com/vamsii777/RazorpayKit.git", from: "0.0.8")
]
```


## Using the API

Initialize the `RazorpayClient` with your Razorpay API key, secret, and environment. This client will be your gateway to interacting with the Razorpay API.


```swift
let httpClient = HTTPClient(...)
let razorpay = RazorpayClient(httpClient: httpClient, key: "rzp_test_12345", secret: "your_secret", environment: .production)
```

And now you have access to the APIs via `razorpay`.

The APIs you have available correspond to what's implemented.

For example to use the `orders` API, the razorpayClient has a property to access that API via routes.

#### Creating an Order

```swift
let orderData = [
"amount": 50000, // Specify amount in the smallest currency unit.
"currency": "INR",
"receipt": "order_rcptid_11"
]

let order = try await razorpayClient.order.create(data: orderData)
print("Created Order: \(order)")
```

#### Fetching a Payment

```swift
let paymentId = "pay_29QQoUBi66xm2f"
let payment = try await razorpayClient.payment.fetch(paymentID: paymentId)
print("Fetched Payment: \(payment)")
```

#### Managing Subscriptions

```swift
let subscriptionId = "sub_00000000000001"
let subscription = try await razorpayClient.subscription.fetch(subscriptionID: subscriptionId)
print("Fetched Subscription: \(subscription)")
```

## What's Implemented

### Core Resources
* [x] **Accounts**
* [x] **Addons**
* [x] **Cards**
* [x] **Customers**
* [x] **Fund Accounts**
* [x] **IIN (Issuer Identification Number)**
* [x] **Invoices**
* [x] **Items**
* [x] **Orders**
* [x] **Payments**
* [x] **Payment Links**
* [x] **Products**
* [x] **QR Codes**
* [x] **Refunds**
* [x] **Settlements**
* [x] **Stakeholders**
* [x] **Subscriptions**
* [x] **Tokens**
* [x] **Transfers**
* [x] **Virtual Accounts**
* [x] **Webhooks**

### Additional Features
* [x] **Authentication**: Securely authenticate using your Razorpay key and secret.
* [x] **Headers Management**: Customize request headers for special use cases such as idempotent requests.
* [x] **Asynchronous API Calls**: Support for Swift's modern async/await pattern for clean and simple asynchronous API calls.


## LICENSE
RazorpayKit is available under the MIT license. See the [LICENSE](LICENSE) file for more info.
31 changes: 31 additions & 0 deletions Sources/RazorpayKit/Constants/APIConstants.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
public struct APIConstants {
static let baseURL = "https://api.razorpay.com"
static let v1 = "/v1"
static let v2 = "/v2"
static let orderURL = "/orders"
static let invoiceURL = "/invoices"
static let paymentURL = "/payments"
static let paymentLinkURL = "/payment_links"
static let refundURL = "/refunds"
static let cardURL = "/cards"
static let customerURL = "/customers"
static let addonURL = "/addons"
static let transferURL = "/transfers"
static let virtualAccountURL = "/virtual_accounts"
static let subscriptionURL = "/subscriptions"
static let planURL = "/plans"
static let qrCodeURL = "/payments/qr_codes"
static let fundAccountURL = "/fund_accounts"
static let settlementURL = "/settlements"
static let itemURL = "/items"
static let methodsURL = "/methods"
static let accountURL = "/accounts"
static let stakeholderURL = "/stakeholders"
static let productURL = "/products"
static let tncURL = "/tnc"
static let iinURL = "/iins"
static let webhookURL = "/webhooks"
static let iin: String = "/iins"
static let tnc: String = "/tnc"
static let webhook: String = "/webhooks"
}
5 changes: 5 additions & 0 deletions Sources/RazorpayKit/Constants/ErrorCode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
enum ErrorCode: String {
case badRequestError = "BAD_REQUEST_ERROR"
case gatewayError = "GATEWAY_ERROR"
case serverError = "SERVER_ERROR"
}
31 changes: 31 additions & 0 deletions Sources/RazorpayKit/Errors/RZPError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Foundation

// Define a custom error type that encompasses various Razorpay errors.
enum RZPError: Error {
case badRequestError(message: String, internalErrorCode: String?, field: String?, description: String?, code: String?)
case serverError(message: String, internalErrorCode: String?, field: String?, description: String?, code: String?)
case gatewayError(message: String, internalErrorCode: String?, field: String?, description: String?, code: String?)
case signatureVerificationError(message: String, internalErrorCode: String?, field: String?, description: String?, code: String?)

// Custom string representation of the error
var errorDescription: String {
switch self {
case .badRequestError(let message, _, _, _, _),
.serverError(let message, _, _, _, _),
.gatewayError(let message, _, _, _, _),
.signatureVerificationError(let message, _, _, _, _):
return message
}
}

var detailedError: String {
switch self {
case .badRequestError(message: let message, internalErrorCode: let code, field: let field, description: let description, code: let errorCode):
return "BadRequestError: \(message), Code: \(code ?? "N/A"), Field: \(field ?? "N/A"), Description: \(description ?? "N/A"), ErrorCode: \(errorCode ?? "N/A")"
// Add similar handling for other cases
default:
return errorDescription
}
}
}

16 changes: 16 additions & 0 deletions Sources/RazorpayKit/RazorpayAPIRoute.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Foundation
import NIOHTTP1

public protocol RazorpayAPIRoute {
var headers: HTTPHeaders { get set }

/// Headers to send with the request.
mutating func addHeaders(_ headers: HTTPHeaders) -> Self
}

extension RazorpayAPIRoute {
public mutating func addHeaders(_ headers: HTTPHeaders) -> Self {
headers.forEach { self.headers.replaceOrAdd(name: $0.name, value: $0.value) }
return self
}
}
Loading

0 comments on commit 0ed08b1

Please sign in to comment.