snippe 0.1.0

Async Rust client for the Snippe payments API (Tanzania) — collections, hosted checkout sessions, disbursements, and verified webhooks.
Documentation
//! Integration tests for the Sessions API.

use serde_json::json;
use snippe::models::session::{AllowedMethod, CreateSessionRequest, SessionStatus};
use snippe::Client;
use wiremock::matchers::{body_json, method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};

fn client_for(server: &MockServer) -> Client {
    Client::builder()
        .api_key("snp_test_key")
        .base_url(server.uri())
        .build()
        .unwrap()
}

#[tokio::test]
async fn create_fixed_amount_session() {
    let server = MockServer::start().await;

    let response = json!({
        "code": 201,
        "data": {
            "reference": "sess_abc123",
            "status": "pending",
            "amount": 50000,
            "currency": "TZS",
            "checkout_url": "https://snippe.me/checkout/xyz",
            "short_code": "Ax7kM2",
            "payment_link_url": "https://snippe.me/p/Ax7kM2",
            "expires_at": "2026-02-26T11:00:00Z"
        }
    });

    let expected = json!({
        "amount": 50000,
        "currency": "TZS",
        "allowed_methods": ["mobile_money", "qr"],
        "description": "Order #1"
    });

    Mock::given(method("POST"))
        .and(path("/api/v1/sessions"))
        .and(body_json(expected))
        .respond_with(ResponseTemplate::new(201).set_body_json(response))
        .mount(&server)
        .await;

    let client = client_for(&server);
    let req = CreateSessionRequest::fixed_amount(50_000)
        .with_allowed_methods([AllowedMethod::MobileMoney, AllowedMethod::Qr])
        .with_description("Order #1");
    let session = client.sessions().create(&req, None).await.unwrap();

    assert_eq!(session.reference, "sess_abc123");
    assert_eq!(session.status, SessionStatus::Pending);
    assert_eq!(session.amount, Some(50_000));
    assert!(session.payment_link_url.is_some());
}

#[tokio::test]
async fn cancel_session() {
    let server = MockServer::start().await;
    Mock::given(method("POST"))
        .and(path("/api/v1/sessions/sess_1/cancel"))
        .respond_with(ResponseTemplate::new(200).set_body_json(json!({
            "data": {
                "reference": "sess_1",
                "status": "cancelled",
                "amount": 50000,
                "currency": "TZS",
                "checkout_url": "https://snippe.me/checkout/xyz",
                "expires_at": "2026-02-26T11:00:00Z"
            }
        })))
        .mount(&server)
        .await;

    let client = client_for(&server);
    let session = client.sessions().cancel("sess_1").await.unwrap();
    assert_eq!(session.status, SessionStatus::Cancelled);
    assert!(session.status.is_terminal());
}