Skip to content

Salesforce ​

Salesforce chamando o produto ​

  1. Setup → Named Credentials → External Credentials → New: protocolo Custom; crie um Principal com o parâmetro de autenticação ApiKey = sua chave pk_live_....
  2. Em Custom Headers da External Credential: Authorization = Bearer {!$Credential.ProtonFiscalApi.ApiKey}.
  3. Named Credential ProtonFiscalApi com URL https://app.fiscal.protoncode.com.br/api/v1 usando a External Credential.
  4. Dê acesso ao Principal pelo Permission Set dos usuários/integração.
apex
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:ProtonFiscalApi/invoices');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setHeader('Idempotency-Key', 'opp-' + opp.Id);
req.setBody(JSON.serialize(new Map<String, Object>{
    'external_ref' => 'sf:' + opp.Id,
    'taker' => new Map<String, Object>{ 'document' => acc.CNPJ__c, 'name' => acc.Name },
    'service' => new Map<String, Object>{ 'description' => opp.Description, 'amount_cents' => (Long) (opp.Amount * 100) }
}));
HttpResponse res = new Http().send(req);

Em Flow: ação HTTP Callout apontando para a Named Credential ProtonFiscalApi.

Proton Fiscal avisando o Salesforce ​

Crie um endpoint Apex REST e cadastre a URL do site público (ou Experience Cloud) como webhook. Valide a assinatura com o exemplo Apex de Webhooks antes de processar.

apex
@RestResource(urlMapping='/fiscal/webhook')
global without sharing class ProdutoWebhook {
    @HttpPost
    global static void receive() {
        RestRequest req = RestContext.request;
        String body = req.requestBody.toString();
        String sig = req.headers.get('X-Proton-Signature');
        if (!WebhookVerifier.verify(ProdutoSettings__c.getOrgDefaults().Secret__c, sig, body)) {
            RestContext.response.statusCode = 401;
            return;
        }
        // Enfileire o processamento (Queueable) e responda rápido.
        System.enqueueJob(new ProcessarEventoFiscal(body, req.headers.get('traceparent')));
        RestContext.response.statusCode = 202;
    }
}