-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
John Doe
committed
Jun 23, 2022
1 parent
161741c
commit 752cf00
Showing
6 changed files
with
438 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Qiwi P2P-счета | ||
|
||
Библиотека для работы с Qiwi P2P-счетами. Поддерживает создание ссылок для создания счёта на стороне клиента и непосредственную работу с API P2P-счетов. | ||
|
||
Документация P2P-счетов: https://developer.qiwi.com/ru/p2p-payments/ | ||
|
||
Документация этой библиотеки: https://pkg.go.dev/github.com/nickname76/qiwip2p | ||
|
||
## Пример использования | ||
|
||
```Go | ||
package main | ||
|
||
import ( | ||
"log" | ||
"time" | ||
|
||
"github.com/nickname76lib/qiwip2p" | ||
) | ||
|
||
func main() { | ||
api := qiwip2p.NewAPI("PUBLIC_KEY", "SECRET_KEY") | ||
bill, err := api.CreateBill("test12345", &qiwip2p.BillMetadata{ | ||
Comment: "Test Comment", | ||
Amount: &qiwip2p.BillMetadataAmount{ | ||
Value: "99.99", | ||
Currency: qiwip2p.CurrencyRUB, | ||
}, | ||
CustomFields: map[string]string{ | ||
qiwip2p.CustomFieldOptionThemeCode: "THEME_CODE", | ||
"test_custom_field": "123456", | ||
}, | ||
ExpirationDateTime: qiwip2p.FormatBillMetadataDateTime(time.Now().Add(time.Hour)), | ||
}) | ||
if err != nil { | ||
log.Fatalf("Ошибка: %w", err) | ||
} | ||
|
||
log.Panicln(bill) | ||
} | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package qiwip2p | ||
|
||
import "time" | ||
|
||
// Идентификатор счёта | ||
type BillID string | ||
|
||
// Идентификатор в сервисе приёма платежей | ||
type SiteID string | ||
|
||
// Данные о счёте | ||
type BillMetadata struct { | ||
// Ваш идентификатор в сервисе приема платежей для физических лиц p2p.qiwi.com. | ||
// НЕ ИСПОЛЬЗОВАТЬ С CreateBill(). | ||
SiteID SiteID `json:"siteId,omitempty"` | ||
// Идентификатор выставляемого счёта в вашей системе. Может быть длиной <=200. | ||
// Он должен быть уникальным, и генерироваться на вашей стороне любым способом. | ||
// Идентификатором может быть любая уникальная последовательность букв или цифр. | ||
// Также разрешено использование символа подчеркивания (_) и дефиса (-). | ||
// НЕ ИСПОЛЬЗОВАТЬ С CreateBill(). | ||
BillID BillID `json:"billId,omitempty"` | ||
// Ссылка на созданную форму. Перенаправьте пользователя | ||
// по этой ссылке для оплаты счета или используйте | ||
// библиотеку Popup, чтобы открыть форму во всплывающем окне. | ||
// https://developer.qiwi.com/ru/p2p-payments/#popup | ||
// НЕ ИСПОЛЬЗОВАТЬ С CreateBill(). | ||
PayURL string `json:"payUrl,omitempty"` | ||
// Идентификаторы пользователя. | ||
Customer *CustomerIdentificators `json:"customer,omitempty"` | ||
// Комментарий к счету. | ||
Comment string `json:"comment,omitempty"` | ||
// Информация о сумме счета. | ||
Amount *BillMetadataAmount `json:"amount,omitempty"` | ||
// Информация о статусе счета. | ||
// НЕ ИСПОЛЬЗОВАТЬ С CreateBill(). | ||
Status *BillMetadataStatus `json:"status,omitempty"` | ||
// Объект строковых дополнительных параметров. Возможные элементы: paySourcesFilter, themeCode | ||
// Может также включать поля (см. константы этого модуля): | ||
// CustomFieldOptionPaySourcesFilter (с возможными значениями: PaySourceQiwi, PaySourceCard, PaySourceQiwiAndCard) | ||
// и CustomFieldOptionThemeCode. | ||
CustomFields map[string]string `json:"customFields,omitempty"` | ||
// Системная дата создания счета. Формат даты: `ГГГГ-ММ-ДДTчч:мм:сс±чч:мм`. | ||
// НЕ ИСПОЛЬЗОВАТЬ С CreateBill(). | ||
CreationDateTime string `json:"creationDateTime,omitempty"` | ||
// Срок действия созданной формы для перевода. Формат даты: `ГГГГ-ММ-ДДTчч:мм:сс±чч:мм`. | ||
ExpirationDateTime string `json:"expirationDateTime,omitempty"` | ||
} | ||
|
||
// Идентификаторы пользователя | ||
type CustomerIdentificators struct { | ||
// Номер телефона пользователя (в международном формате). | ||
Phone string `json:"phone,omitempty"` | ||
// E-mail пользователя. | ||
Email string `json:"email,omitempty"` | ||
// Идентификатор пользователя в вашей системе. | ||
Account string `json:"account,omitempty"` | ||
} | ||
|
||
// Валюта счёта | ||
type Currency string | ||
|
||
const ( | ||
// Российский рубль | ||
CurrencyRUB Currency = "RUB" | ||
// Казахстанский тенге | ||
CurrencyKZT Currency = "KZT" | ||
) | ||
|
||
// Сумма счёта | ||
type BillMetadataAmount struct { | ||
// Сумма счета, округленная до 2 знаков после запятой в меньшую сторону. | ||
Value string `json:"value,omitempty"` | ||
// Валюта суммы счета (Alpha-3 ISO 4217 код). Доступные значения: CurrencyRUB, CurrencyKZT (см. константы модуля) | ||
Currency Currency `json:"currency,omitempty"` | ||
} | ||
|
||
// Статус оплаты счета. | ||
type BillMetadataStatusValue string | ||
|
||
const ( | ||
// Счет выставлен, ожидает оплаты. | ||
BillMetadataStatusValueWaiting BillMetadataStatusValue = "WAITING" | ||
// Счет оплачен. Финальный. | ||
BillMetadataStatusValuePaid BillMetadataStatusValue = "PAID" | ||
// Время жизни счета истекло. Счет не оплачен. Финальный. | ||
BillMetadataStatusValueExpired BillMetadataStatusValue = "EXPIRED" | ||
// Счет отклонен. Финальный. | ||
BillMetadataStatusValueRejected BillMetadataStatusValue = "REJECTED" | ||
) | ||
|
||
type BillMetadataStatus struct { | ||
// Текущий статус счета. | ||
Value BillMetadataStatusValue `json:"value,omitempty"` | ||
// Дата обновления статуса. Формат даты: `ГГГГ-ММ-ДДTчч:мм:сс±чч:мм`. | ||
ChangedDateTime string `json:"changedDateTime,omitempty"` | ||
} | ||
|
||
const ( | ||
// При открытии формы будут отображаться только указанные | ||
// способы перевода, если они доступны. Возможные значения см. ниже. | ||
CustomFieldOptionPaySourcesFilter = "paySourcesFilter" | ||
// QIWI Кошелек. | ||
PaySourceQiwi = "qw" | ||
// Банковская карта. | ||
PaySourceCard = "card" | ||
// QIWI Кошелек и банковская карта. | ||
PaySourceQiwiAndCard = PaySourceQiwi + "," + PaySourceCard | ||
) | ||
|
||
const ( | ||
// Код персонализации вашей формы. Может быть длиной <=255. | ||
// https://developer.qiwi.com/ru/p2p-payments/#custom | ||
CustomFieldOptionThemeCode = "themeCode" | ||
) | ||
|
||
// Форматирует time.Time в значение формата для полей с datetime в BillMetadata | ||
func FormatBillMetadataDateTime(t time.Time) string { | ||
return t.Format(time.RFC3339Nano) | ||
} | ||
|
||
// Парсит значение поля с datetime из BillMetedata | ||
func ParseBillMetadataDateTime(changedDateTime string) (time.Time, error) { | ||
return time.Parse(time.RFC3339Nano, changedDateTime) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package qiwip2p | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/google/go-querystring/query" | ||
) | ||
|
||
// Необязательные параметры для выставления сч1та. | ||
type OplataCreateOptions struct { | ||
// Идентификатор выставляемого сч1та в вашей системе. Может быть длиной <=200. | ||
// Он должен быть уникальным, и генерироваться на вашей стороне любым способом. | ||
// Идентификатором может быть любая уникальная последовательность букв или цифр. | ||
// Также разрешено использование символа подчеркивания (_) и дефиса (-). | ||
BillID BillID `url:"billId,omitempty"` | ||
// Сумма, на которую выставляется счёт, округленная в меньшую сторону до 2 десятичных знаков. | ||
// Должна быть не больше 6 знаков до запятой и не больше 2 знаков после запятой. | ||
// Пример: `Amount: "123456.78"` | ||
Amount string `url:"amount,omitempty"` | ||
// Номер телефона пользователя (в международном формате). | ||
Phone string `url:"phone,omitempty"` | ||
// E-mail пользователя. | ||
Email string `url:"email,omitempty"` | ||
// Идентификатор пользователя в вашей системе. | ||
Account string `url:"account,omitempty"` | ||
// Комментарий к счету. Может быть длиной <=255. | ||
Comment string `url:"comment,omitempty"` | ||
// Дополнительные данные счета. Может быть длиной суммарно <=255. | ||
// Может также включать поля (см. константы этого модуля): | ||
// CustomFieldOptionPaySourcesFilter (с возможными значениями: PaySourceQiwi, PaySourceCard, PaySourceQiwiAndCard) | ||
// и CustomFieldOptionThemeCode | ||
CustomFields map[string]string `url:"customFields,omitempty"` | ||
// Дата и время по МСК (UTC+3), до которого счёт будет актуален. Формат - ГГГГ-ММ-ДДTччмм, см. ConvertTimeToLifetimeValue(). | ||
// Если перевод по счету не будет произведен до этой даты, | ||
// ему присваивается финальный статус `EXPIRED` и последующий перевод станет невозможен. | ||
// **Внимание! По истечении 45 суток от даты выставления счёт автоматически будет переведен в финальный статус** | ||
Lifetime string `url:"lifetime,omitempty"` | ||
// URL для переадресации на ваш сайт в случае успешного перевода | ||
SuccessURL string `url:"successUrl,omitempty"` | ||
} | ||
|
||
// Создаёт ссылку при переходе по которой отображается форма с выбором способа перевода. | ||
// publicKey - публичный ключ Qiwi P2p API. Не может быть пустым. | ||
// При использовании этого способа нельзя гарантировать, что | ||
// все счета выставлены вами, в отличие от выставления счёта по API. | ||
// | ||
// https://developer.qiwi.com/ru/p2p-payments/#http-invoice | ||
func (api *API) CreateOplataURL(options *OplataCreateOptions) string { | ||
// Ошибка не может возникать в этом вызове | ||
v, err := query.Values(options) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
v.Add("publicKey", api.PublicKey) | ||
|
||
queryStr := v.Encode() | ||
|
||
return "https://oplata.qiwi.com/create?" + queryStr | ||
} | ||
|
||
// Форматирует time.Time в значение для `OplataCreateOptions.Lifetime` | ||
func FormatTimeToLifetime(t time.Time) string { | ||
return t.Format("2006-01-02T150405") | ||
} | ||
|
||
// Парсит значение `OplataCreateOptions.Lifetime` в time.Time | ||
func ParseLifetime(str string) (time.Time, error) { | ||
return time.Parse("2006-01-02T150405", str) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module github.com/nickname76lib/qiwip2p | ||
|
||
go 1.18 | ||
|
||
require ( | ||
github.com/google/go-querystring v1.1.0 | ||
github.com/json-iterator/go v1.1.12 | ||
github.com/valyala/fasthttp v1.37.0 | ||
) | ||
|
||
require ( | ||
github.com/andybalholm/brotli v1.0.4 // indirect | ||
github.com/klauspost/compress v1.15.6 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
github.com/modern-go/reflect2 v1.0.2 // indirect | ||
github.com/valyala/bytebufferpool v1.0.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= | ||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= | ||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= | ||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | ||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= | ||
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= | ||
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= | ||
github.com/klauspost/compress v1.15.6 h1:6D9PcO8QWu0JyaQ2zUMmu16T1T+zjjEpP91guRsvDfY= | ||
github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= | ||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | ||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= | ||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||
github.com/valyala/fasthttp v1.35.0 h1:wwkR8mZn2NbigFsaw2Zj5r+xkmzjbrA/lyTmiSlal/Y= | ||
github.com/valyala/fasthttp v1.35.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= | ||
github.com/valyala/fasthttp v1.37.0 h1:7WHCyI7EAkQMVmrfBhWTCOaeROb1aCBiTopx63LkMbE= | ||
github.com/valyala/fasthttp v1.37.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= | ||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= | ||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= | ||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
Oops, something went wrong.