Skip to content

Commit 592cd09

Browse files
authored
Merge pull request #65 from morukele/dev
feat: added support for apple pay endpoints
2 parents 0af63f4 + 00e5832 commit 592cd09

8 files changed

Lines changed: 174 additions & 3 deletions

File tree

src/client.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
//! =========
33
//! This file contains the Paystack API client, and it associated endpoints.
44
use crate::{
5-
CustomersEndpoints, DedicatedVirtualAccountEndpoints, HttpClient, SubaccountEndpoints,
6-
TerminalEndpoints, TransactionEndpoints, TransactionSplitEndpoints, VirtualTerminalEndpoints,
5+
ApplePayEndpoints, CustomersEndpoints, DedicatedVirtualAccountEndpoints, HttpClient,
6+
SubaccountEndpoints, TerminalEndpoints, TransactionEndpoints, TransactionSplitEndpoints,
7+
VirtualTerminalEndpoints,
78
};
89
use std::sync::Arc;
910

@@ -24,6 +25,8 @@ pub struct PaystackClient<T: HttpClient + Default> {
2425
pub customers: CustomersEndpoints<T>,
2526
/// Dedicated Virtual Account API route
2627
pub dedicated_virtual_account: DedicatedVirtualAccountEndpoints<T>,
28+
/// Apple Pay API route
29+
pub apple_pay: ApplePayEndpoints<T>,
2730
}
2831

2932
impl<T: HttpClient + Default> PaystackClient<T> {
@@ -41,6 +44,7 @@ impl<T: HttpClient + Default> PaystackClient<T> {
4144
Arc::clone(&key),
4245
Arc::clone(&http),
4346
),
47+
apple_pay: ApplePayEndpoints::new(Arc::clone(&key), Arc::clone(&http)),
4448
}
4549
}
4650
}

src/endpoints/apple_pay.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
//! Apple Pay
2+
//! THe Apple Pay API allows you register your application's top-level domain or subdomain.
3+
4+
use std::{marker::PhantomData, sync::Arc};
5+
6+
use serde_json::json;
7+
8+
use crate::{ApplePayResponseData, HttpClient, PaystackAPIError, PaystackResult, Response};
9+
10+
#[derive(Debug, Clone)]
11+
pub struct ApplePayEndpoints<T: HttpClient + Default> {
12+
/// Paystack API key
13+
key: String,
14+
/// Base URL for the apple pay route
15+
base_url: String,
16+
/// Http client for the route
17+
http: Arc<T>,
18+
}
19+
20+
impl<T: HttpClient + Default> ApplePayEndpoints<T> {
21+
/// Creates a new ApplePayEndpoints instance
22+
///Creates a new ApplePayEndpoints instance
23+
///
24+
/// # Arguments
25+
/// * `key` - The Paystack API key
26+
/// * `http` - The HTTP client implementation to use for API requests
27+
///
28+
/// # Returns
29+
/// A new ApplePayEndpoints instance
30+
pub fn new(key: Arc<String>, http: Arc<T>) -> ApplePayEndpoints<T> {
31+
let base_url = String::from("https://api.paystack.co/apple-pay/domain");
32+
ApplePayEndpoints {
33+
key: key.to_string(),
34+
base_url,
35+
http,
36+
}
37+
}
38+
39+
/// Register a top-level domain or subdomain for your Apple Pay integration.
40+
///
41+
/// # Arguments
42+
/// * `domain_name` - The domain name to be registered with Apple Pay
43+
///
44+
/// # Returns
45+
/// A Result containing the registration response or an error
46+
pub async fn register_domain(
47+
&self,
48+
domain_name: String,
49+
) -> PaystackResult<PhantomData<String>> {
50+
let url = format!("{}", self.base_url);
51+
let body = json!({
52+
"domainName": domain_name
53+
});
54+
55+
let response = self.http.post(&url, &self.key, &body).await;
56+
57+
match response {
58+
Ok(response) => {
59+
let parsed_response: Response<PhantomData<String>> =
60+
serde_json::from_str(&response)
61+
.map_err(|e| PaystackAPIError::ApplePay(e.to_string()))?;
62+
63+
Ok(parsed_response)
64+
}
65+
Err(e) => Err(PaystackAPIError::ApplePay(e.to_string())),
66+
}
67+
}
68+
69+
/// Lists all domains registered on your integration
70+
///
71+
/// # Returns
72+
/// A Result containing the list of registered domains or an error
73+
pub async fn list_domains(&self) -> PaystackResult<ApplePayResponseData> {
74+
let url = format!("{}", self.base_url);
75+
76+
let response = self.http.get(&url, &self.key, None).await;
77+
78+
match response {
79+
Ok(response) => {
80+
let parsed_response: Response<ApplePayResponseData> =
81+
serde_json::from_str(&response)
82+
.map_err(|e| PaystackAPIError::ApplePay(e.to_string()))?;
83+
84+
Ok(parsed_response)
85+
}
86+
Err(e) => Err(PaystackAPIError::ApplePay(e.to_string())),
87+
}
88+
}
89+
90+
pub async fn unregister_domain(
91+
&self,
92+
domain_name: String,
93+
) -> PaystackResult<PhantomData<String>> {
94+
let url = format!("{}", self.base_url);
95+
let body = json!({
96+
"domainName": domain_name
97+
});
98+
99+
let response = self.http.delete(&url, &self.key, &body).await;
100+
101+
match response {
102+
Ok(response) => {
103+
let parsed_response: Response<PhantomData<String>> =
104+
serde_json::from_str(&response)
105+
.map_err(|e| PaystackAPIError::ApplePay(e.to_string()))?;
106+
107+
Ok(parsed_response)
108+
}
109+
Err(e) => Err(PaystackAPIError::ApplePay(e.to_string())),
110+
}
111+
}
112+
}

src/endpoints/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod apple_pay;
12
pub mod customers;
23
pub mod dedicated_virtual_account;
34
pub mod subaccount;
@@ -7,6 +8,7 @@ pub mod transaction_split;
78
pub mod virtual_terminal;
89

910
// public re-export
11+
pub use apple_pay::*;
1012
pub use customers::*;
1113
pub use dedicated_virtual_account::*;
1214
pub use subaccount::*;

src/errors.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub enum PaystackAPIError {
3131
/// Error associated with customer
3232
#[error("Customer Error: {0}")]
3333
Customer(String),
34-
#[error("Dedicated Virtual Account: {0}")]
34+
#[error("Dedicated Virtual Account Error: {0}")]
3535
DedicatedVirtualAccount(String),
36+
#[error("Apple Pay Error: {0}")]
37+
ApplePay(String),
3638
}

src/models/apple_pay.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
4+
pub struct ApplePayResponseData {
5+
#[serde(rename = "domainNames")]
6+
pub domain_names: Vec<String>,
7+
}

src/models/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod apple_pay;
12
pub mod authorization;
23
pub mod bearer;
34
pub mod channel;
@@ -16,6 +17,7 @@ pub mod transaction_split;
1617
pub mod virtual_terminal;
1718

1819
// public re-export
20+
pub use apple_pay::*;
1921
pub use authorization::*;
2022
pub use bearer::*;
2123
pub use channel::*;

tests/api/apple_pay.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use crate::helpers::get_paystack_client;
2+
3+
#[tokio::test]
4+
async fn can_list_domains() {
5+
let client = get_paystack_client();
6+
7+
let res = client
8+
.apple_pay
9+
.list_domains()
10+
.await
11+
.expect("unable to list domains");
12+
13+
assert!(res.status);
14+
assert!(res
15+
.message
16+
.contains("Apple Pay registered domains retrieved"))
17+
}
18+
19+
#[tokio::test]
20+
async fn can_unregister_domain() {
21+
// Arrange
22+
let client = get_paystack_client();
23+
24+
// Act
25+
let domain_name = "example.com".to_string();
26+
let res = client
27+
.apple_pay
28+
.unregister_domain(domain_name)
29+
.await
30+
.expect("unable to unregister domain");
31+
32+
// Assert
33+
assert!(res.status);
34+
assert!(res
35+
.message
36+
.contains("Domain successfully unregistered on Apple Pay"));
37+
}
38+
39+
// TODO: need elevated permission for some tests on this route
40+
#[tokio::test]
41+
async fn can_register_domain() {}

tests/api/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod apple_pay;
12
pub mod charge;
23
pub mod customer;
34
pub mod dedicated_virtual_account;

0 commit comments

Comments
 (0)