Skip to main content

Specs and DSL

Prism uses a domain-specific language (DSL) built on Protocol Buffers and Rust Types that catches integration errors at compile time. It enforces the right thing so that AI agents and Developers can code at ease when adding new integrations or enhancements to the Prism codebase.

The Prism DSL

DSL for Connector Development

The ConnectorIntegration trait defines the contract that every connector must implement. This trait ensures consistent behavior across all payment processor integrations. Mistakes are caught early at compile time, rather than late.

Core trait methods:

MethodPurposeWhen Called
get_headersBuild HTTP headers for the requestBefore every API call
get_urlConstruct the endpoint URLBefore every API call
get_request_bodySerialize the request payloadBefore every API call
build_requestAssemble the complete HTTP requestBefore every API call
handle_responseParse successful responsesAfter 2xx response
build_error_responseParse error responsesAfter 4xx/5xx response
get_connector_transaction_idExtract transaction IDAfter successful response

Example implementation:

impl ConnectorIntegration<Authorize, AuthorizeRequest, AuthorizeResponse> for Stripe {
fn get_headers(
&self,
req: &AuthorizeRequest,
connectors: &Connectors,
) -> CustomResult<Vec<(String, SecretString)>, errors::IntegrationError> {
// Build authentication headers
vec![
("Authorization".to_string(), format!("Bearer {}", self.api_key).into()),
("Content-Type".to_string(), "application/json".to_string().into()),
]
}

fn get_url(
&self,
_req: &AuthorizeRequest,
connectors: &Connectors,
) -> CustomResult<String, errors::IntegrationError> {
Ok(format!("{}/v1/payment_intents", self.base_url))
}

fn get_request_body(
&self,
req: &AuthorizeRequest,
) -> CustomResult<RequestContent, errors::IntegrationError> {
// Transform unified request to Stripe-specific payload
let stripe_payload = StripeAuthorizeRequest::try_from(req)?;
Ok(RequestContent::Json(Box::new(stripe_payload)))
}

fn handle_response(
&self,
data: &AuthorizeRequest,
event_builder: Option<&mut ConnectorEvent>,
res: Response,
) -> CustomResult<PaymentsResponseData, errors::ConnectorError> {
// Parse Stripe response into unified format
let response: StripeAuthorizeResponse = res.response?.parse_struct("StripeAuthorizeResponse")?;
Ok(PaymentsResponseData {
status: response.status.into(),
connector_transaction_id: response.id,
// ... other fields
})
}

fn build_error_response(
&self,
res: Response,
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
// Transform Stripe error into unified error format
let error: StripeErrorResponse = res.response?.parse_struct("StripeErrorResponse")?;
Ok(ErrorResponse {
code: error.code,
message: error.message,
unified_code: map_stripe_error_to_unified(&error),
})
}
}

Additionally a macro system enforces that adapters implement all the required methods.

// This macro generates compile-time checks
macros::macro_connector_implementation!(
connector: Stripe,
flow_name: Authorize,
http_method: Post,
// ... other parameters
);

If you forget to implement build_error_response, the macro invocation fails at compile time with a clear error message: "Connector Stripe is missing required method build_error_response for flow Authorize".

Protocol Buffers

Prism defines payment operations as Protocol Buffer schemas. These generate type-safe bindings in every supported language, which is the core of the unification. It provides compile-time guarantees irrespective of the programming languages you use the SDK with.

Proto definition:

message AuthorizeRequest {
Money amount = 1; // Required
string merchant_order_id = 2; // Required
PaymentMethod payment_method = 3; // Required
CaptureMethod capture_method = 4; // Required
AuthenticationType authentication_type = 5; // Optional, defaults to NO_THREE_DS
string customer_id = 6; // Optional
string email = 7; // Optional
string description = 8; // Optional
map<string, string> metadata = 9; // Optional
string return_url = 10; // Optional, required for 3DS
}

message Money {
int64 minor_amount = 1; // Required
string currency = 2; // Required, ISO 4217 format
}