Custom Payment Provider
Pro edition
This section introduces a Pro edition feature.
In addition to the payment providers already supported by Cloudreve, you can also integrate your own payment platform by implementing Cloudreve's payment interface, or bridge other third-party platforms.
To implement a custom payment interface, you need an independent HTTP service that provides:
- An API endpoint to:
- Handle Cloudreve's payment creation requests and return a payment page URL;
- Handle Cloudreve's requests to query the payment status of an order;
- After the customer completes the payment, send an HTTP request to a specified URL to notify Cloudreve of the payment completion.
Implementing the Payment Interface
Implement your payment interface according to the specifications in this chapter, deploy the interface, and ensure it can communicate with Cloudreve over the network.
Warning
The custom payment API for version 3 is not compatible with version 4.
Create Order POST <your-payment-endpoint>
When a new order is created, Cloudreve sends a request to your payment interface.
Request Headers
Name | Type | Description |
---|---|---|
Authorization | String | A signature calculated using the Communication key you set in the backend. See Verify Signature for details. |
X-Cr-Version | String | Cloudreve version number |
X-Cr-Site-Id | String | Cloudreve site ID, which can be used to distinguish different sites |
X-Cr-Site-Url | String | The main site URL of Cloudreve. |
Request Body
The request body is sent in JSON format and includes the following fields:
Name | Type | Description |
---|---|---|
name | String | Payment name |
order_no | String | Order number |
notify_url | String | Callback notification URL |
amount | Number | Payment amount, using the smallest unit of currency |
currency | String | ISO 4217 code of the currency |
Request Example
POST /order
Host: examplepayment.com
Authorization: Bearer Vep6hl1x8fiQLasEauMEUqxFKyEqSXb9D_BBQpOiTd8=:1676027218
X-Cr-Site-Url: https://demo.cloudreve.org
X-Cr-Site-Id: b7de8bba-8f86-40fe-8171-c2625b6c4a61
X-Cr-Version: 4.0.0
{
"name": "Unlimited Storage",
"order_no": "20230209190648343421",
"notify_url": "http://demo.cloudreve.org/api/v4/callback/custom/20230209190648343421",
"amount": 8900,
"currency": "CNY"
}
Expected Response
Regardless of whether the order creation is successful, the HTTP response code should be 200
, with success or failure determined by the code
field in the response body.
HTTP/1.1 200 OK
{
// A successful response is always 0
"code": 0,
// The URL of the payment checkout page, which will be generated as a QR code for the user to scan, or they can choose to open this URL directly
"data": "https://examplepayment.com/checkout/26544743"
}
Query Order Status GET <your-payment-endpoint>
When Cloudreve needs to query the order status, it sends a request to your endpoint.
Request Headers
Name | Type | Description |
---|---|---|
Authorization | String | A signature calculated using the Communication key you set in the backend. See Verify Signature for details. |
X-Cr-Version | String | Cloudreve version number |
X-Cr-Site-Id | String | Cloudreve site ID, which can be used to distinguish different sites |
X-Cr-Site-Url | String | The main site URL of Cloudreve. |
Request Parameters
Request parameters are sent as URL parameters and include the following fields:
Name | Type | Description |
---|---|---|
order_no | String | Order number |
Request Example
GET /order?order_no=20230209190648343421
Host: examplepayment.com
Authorization: Bearer Vep6hl1x8fiQLasEauMEUqxFKyEqSXb9D_BBQpOiTd8=:1676027218
X-Cr-Site-Url: https://demo.cloudreve.org
X-Cr-Site-Id: b7de8bba-8f86-40fe-8171-c2625b6c4a61
X-Cr-Version: 4.0.0
Expected Response
HTTP/1.1 200 OK
{
"code": 0,
// PAID - Paid
// Other values - Not paid
"data": "PAID"
}
Verify Signature
You can set a communication key
in the Cloudreve payment settings. Cloudreve's payment creation requests will use this key for signing and place it in the Authorization header. You can verify this signature using the following algorithm:
Extract the part after Bearer in the Authorization value, split the string by
:
, and the second part is the expiration timestamp of the signature, noted astimestamp
. Verify that it is greater than the current timestamp. The part before:
is noted assignature
;Iterate over all request headers, filter out those prefixed with
X-Cr-
, convert them tokey=value
format, then sort and join the results with&
to form the stringsignedHeaderStr
.
var signedHeader []string
for k, _ := range r.Header {
if strings.HasPrefix(k, "X-Cr-") {
signedHeader = append(signedHeader, fmt.Sprintf("%s=%s", k, r.Header.Get(k)))
}
}
sort.Strings(signedHeader)
signedHeaderStr := strings.Join(signedHeader, "&")
- Encode the request URL's
Path
part, request body, andsignedHeaderStr
as a JSON stringsignContent
.
type RequestRawSign struct {
Path string
Header string
Body string
}
signContent, err := json.Marshal(RequestRawSign{
Path: r.URL.Path,
Header: signedHeaderStr,
Body: string(r.Body),
})
- Concatenate
signContent
andtimestamp
with:
to form the stringsignContentFinal
, and use the HMAC algorithm andCommunication key
to calculate the signature forsignContentFinal
, noted assignActual
.
signContentFinal := fmt.Sprintf("%s:%s", signContent, timestamp)
signActual := hmac.New(sha256.New, []byte(Communication key)).Sum([]byte(signContentFinal))
- Compare
signActual
withsignature
to check for consistency.
Send Callback
After the user completes the payment, you need to send a GET request to the notify_url
specified when the payment was created to notify Cloudreve that the user has completed the payment. If the callback request fails, retry with exponential backoff unless the response explicitly returns an error message and code. An example response from Cloudreve is as follows:
HTTP/1.1 200 OK
{
// A successful response is always 0
"code": 0
}