SDK Java para integração backend com o PicPay Checkout Padrão e Lightbox. Permite criar pagamentos no servidor e obter a URL para redirecionar o consumidor (Checkout Padrão) ou exibir o pagamento em iframe (Checkout Lightbox).
- Java 17+
- Maven 3.6+
Adicione a dependência ao seu pom.xml (ou instale localmente com mvn install):
<dependency>
<groupId>balbucio.picpay4j</groupId>
<artifactId>picpay4j</artifactId>
<version>1.2.0</version>
</dependency>A API E-commerce do PicPay (Checkout Padrão) usa um token do lojista no header x-picpay-token. Obtenha o token no Painel Lojista PicPay.
import com.picpay.checkout.PicPayCheckoutConfig;
import com.picpay.checkout.PicPayCheckoutClient;
PicPayCheckoutConfig config = PicPayCheckoutConfig.sellerToken("SEU_TOKEN_PICPAY")
.build();
PicPayCheckoutClient client = new PicPayCheckoutClient(config);Para uso com a API de Checkout (OAuth 2.0), use as credenciais geradas em Integrações > Checkout > Gerar Token no Painel:
PicPayCheckoutConfig config = PicPayCheckoutConfig.oauth("client_id", "client_secret")
.build();
PicPayCheckoutClient client = new PicPayCheckoutClient(config);A requisição de criação de checkout deve ser feita somente no backend, nunca no frontend, para não expor credenciais.
- Monte a requisição com dados do pedido e do comprador.
- Chame
createPayment. - Redirecione o consumidor para
response.getPaymentUrl().
import com.picpay.checkout.PicPayCheckoutClient;
import com.picpay.checkout.model.*;
// Comprador
Buyer buyer = Buyer.builder()
.firstName("João")
.lastName("Silva")
.document("12345678909") // CPF sem formatação
.build();
// Requisição de pagamento
CreatePaymentRequest request = CreatePaymentRequest.builder()
.referenceId("PEDIDO-12345") // ID único do pedido no seu sistema
.callbackUrl("https://seusite.com/webhook/picpay") // URL para notificações
.returnUrl("https://seusite.com/obrigado") // URL após pagamento
.value(new BigDecimal("99.90"))
.buyer(buyer)
.build();
CreatePaymentResponse response = client.createPayment(request);
// Redirecione o usuário para a página de pagamento do PicPay
String urlCheckout = response.getPaymentUrl(); // usar em redirect HTTP 302
String idTransacao = response.getPicpayTransactionId();No Checkout Lightbox o pagamento ocorre dentro de um iframe na sua página, sem redirecionar o usuário. O backend usa a mesma API; a diferença é só no frontend (exibir a URL em iframe em vez de redirecionar).
- No backend, chame
createPaymentForLightboxcom a mesma requisição do Checkout Padrão. - Retorne ao frontend a URL de
LightboxCheckoutSession.getIframePaymentUrl(). - No frontend, exiba essa URL dentro de um iframe (ou modal com iframe).
// Backend: mesma requisição do Checkout Padrão
CreatePaymentRequest request = CreatePaymentRequest.builder()
.referenceId("PEDIDO-12345")
.callbackUrl("https://seusite.com/webhook/picpay")
.returnUrl("https://seusite.com/obrigado")
.value(new BigDecimal("99.90"))
.buyer(buyer)
.build();
LightboxCheckoutSession session = client.createPaymentForLightbox(request);
// Envie ao frontend (ex.: JSON na resposta da sua API):
// - session.getIframePaymentUrl() → src do iframe
// - session.getReferenceId()
// - session.getPicpayTransactionId()Seu backend pode retornar um JSON com iframePaymentUrl. No frontend (HTML/JS), exiba o checkout em um overlay:
<div id="picpay-lightbox" style="position:fixed;inset:0;background:rgba(0,0,0,0.5);display:none;align-items:center;justify-content:center;z-index:9999;">
<div style="background:#fff;width:90%;max-width:500px;height:80vh;border-radius:8px;overflow:hidden;">
<iframe id="picpay-iframe" src="" style="width:100%;height:100%;border:0;"></iframe>
</div>
</div>
<script>
function openPicPayLightbox(iframePaymentUrl) {
document.getElementById('picpay-iframe').src = iframePaymentUrl;
document.getElementById('picpay-lightbox').style.display = 'flex';
}
// Quando o usuário concluir o pagamento, o PicPay pode redirecionar dentro do iframe
// ou comunicar via postMessage; feche o lightbox e redirecione conforme sua returnUrl.
</script>| Checkout Padrão | Checkout Lightbox | |
|---|---|---|
| Backend | createPayment(request) |
createPaymentForLightbox(request) |
| Resposta | CreatePaymentResponse |
LightboxCheckoutSession |
| Frontend | Redirect do usuário para getPaymentUrl() |
Iframe com getIframePaymentUrl() |
| Experiência | Usuário sai da sua página | Usuário permanece na sua página |
O webhook (callbackUrl) e o fluxo de notificação são os mesmos nos dois modos.
Opcionalmente defina data/hora de expiração do pagamento:
request = CreatePaymentRequest.builder()
// ... outros campos
.expiresAt(OffsetDateTime.now().plusHours(1))
.build();- Backend: seu servidor chama
createPayment(oucreatePaymentForLightbox) e recebe a URL e os IDs. - Checkout Padrão: redirecione o usuário para
paymentUrl. Lightbox: exibaiframePaymentUrlem um iframe. - Pagamento: o usuário paga com cartão, Wallet PicPay ou PIX na página/iframe do PicPay.
- Webhook: o PicPay envia um POST para sua
callbackUrlcom o status do pagamento. - Retorno: o usuário é redirecionado para sua
returnUrlapós concluir (ou o iframe pode ser fechado).
Configure a URL de notificação (webhook) no Painel ou use a callbackUrl da requisição. A notificação virá com dados da transação para você atualizar o pedido.
O PicPay envia um POST para a URL configurada (Painel ou callbackUrl) a cada mudança de status. O SDK oferece objetos tipados para o payload e um parser que não depende de framework: você passa o body e o header event-type e recebe um WebhookEvent.
WebhookEvent– evento raiz:type,eventDate,id,merchantCode, etc.ChargeEventData– quandoevent-type: TransactionUpdateMessage(Wallet, Credit, PIX):status,amount,customer,merchantChargeId,transactions[].Challenge3dsData– quandoevent-type: Challenge3dsUpdateMessage:status,paresStatus,eciRaw,merchantChargeId,chargeId.WebhookTransaction– cada item emtransactions, compaymentType,status,wallet/credit/pixconforme o método de pagamento.
Use com qualquer framework (Servlet, Spring, JAX-RS, etc.): basta o body (String ou InputStream) e o header event-type.
import com.picpay.checkout.webhook.*;
// No seu endpoint (ex.: request.getInputStream(), request.getHeader("event-type"))
WebhookEvent event = client.parseWebhookEvent(bodyString, eventTypeHeader);
// Ou sem o client (parser estático, sem dependência de framework):
WebhookEvent event = WebhookParser.parse(bodyString, eventTypeHeader);
// Com InputStream: WebhookParser.parseFromStream(bodyInputStream, eventTypeHeader);
if (event.isTransactionUpdate()) {
ChargeEventData data = event.getChargeData();
String merchantChargeId = data.getMerchantChargeId();
String status = data.getStatus(); // ex.: PAID, AUTHORIZED, CAPTURED
for (WebhookTransaction tx : data.getTransactions()) {
String paymentType = tx.getPaymentType(); // WALLET, CREDIT, PIX
String txStatus = tx.getStatus();
}
} else if (event.isChallenge3ds()) {
Challenge3dsData data = event.getChallenge3dsData();
String status = data.getStatus(); // ex.: Approved
}InputStream:
WebhookEvent event = client.parseWebhookEvent(request.getInputStream(), request.getHeader("event-type"));Autenticação: o PicPay envia o token no header Authorization. Valide comparando com o token exibido no Painel (Ajustes > Meu checkout > URL de notificação). O SDK não valida o token; isso fica a cargo do seu endpoint.
Documentação: Webhook PicPay.
O SDK permite realizar cancelamento total ou parcial de uma cobrança. O cancelamento está disponível apenas na API de Checkout (OAuth 2.0), não na API E-commerce.
Cancela o valor completo da cobrança:
import com.picpay.checkout.model.RefundRequest;
// merchantChargeId é o ID que você passou ao criar o pagamento (referenceId ou picpayTransactionId)
String merchantChargeId = "PEDIDO-12345";
RefundRequest request = RefundRequest.total();
RefundResponse response = client.refundCharge(merchantChargeId, request);
String status = response.getChargeStatus(); // ex.: REFUNDED, PARTIAL
Integer refundedAmount = response.getRefundedAmount();Cancela apenas uma parte do valor (em centavos ou BigDecimal):
// Cancelar R$ 50,00 de uma cobrança de R$ 100,00
RefundRequest partialRequest = RefundRequest.partial(new BigDecimal("50.00"));
// Ou: RefundRequest.partial(5000); // 5000 centavos = R$ 50,00
RefundResponse response = client.refundCharge(merchantChargeId, partialRequest);
if ("PARTIAL".equals(response.getChargeStatus())) {
// Cancelamento parcial realizado
Integer originalAmount = response.getOriginalAmount(); // 10000 centavos
Integer refundedAmount = response.getRefundedAmount(); // 5000 centavos
Integer remainingAmount = response.getAmount(); // 5000 centavos restantes
}- O cliente deve estar configurado com OAuth 2.0 (
PicPayCheckoutConfig.oauth(...)). - O
merchantChargeIddeve ser o identificador externo único da cobrança (6-36 caracteres). - Após uma tentativa de cancelamento sem sucesso, aguarde 3 minutos antes de tentar novamente.
Documentação: Cancelamento de cobrança | Cancelamento Parcial e Total.
O SDK permite criar cobranças PIX diretamente via API, gerando um QRCode que o consumidor pode pagar via leitura do código ou "Pix Copia e Cola". O pagamento pode ser realizado uma única vez, respeitando o prazo de expiração configurado.
- O cliente deve estar configurado com OAuth 2.0 (
PicPayCheckoutConfig.oauth(...)). - Informações do dispositivo são obrigatórias para análise antifraude.
import com.picpay.checkout.model.*;
// Cliente
ChargeCustomer customer = ChargeCustomer.builder()
.name("João Silva")
.email("joao@example.com")
.documentTypeCpf()
.document("12345678909")
.build();
// Telefone
ChargePhone phone = ChargePhone.builder()
.countryCode("55")
.areaCode("11")
.number("987654321")
.typeMobile()
.build();
// Informações do dispositivo (obrigatório para antifraude)
DeviceInformation device = DeviceInformation.builder()
.ip("192.168.1.1") // IP do cliente
.sessionId("session-123")
.ipCountryCode("BRA")
.ipCity("São Paulo")
.ipRegion("SP")
.build();
// Transação PIX
ChargePixTransaction transaction = ChargePixTransaction.builder()
.amount(new BigDecimal("100.00")) // R$ 100,00
.pixExpiration(600) // QRCode expira em 600 segundos (10 minutos)
.build();
// Requisição de cobrança
ChargePixRequest request = ChargePixRequest.builder()
.paymentSourceGateway() // ou paymentSourceCheckout() se usar checkout
.merchantChargeId("PEDIDO-PIX-12345") // opcional, será gerado se não informado
.customer(customer)
.phone(phone)
.deviceInformation(device)
.transactions(List.of(transaction))
.build();
// Criar cobrança PIX
RefundResponse response = client.createPixCharge(request);
// Obter QRCode PIX
if (response.getTransactions() != null && !response.getTransactions().isEmpty()) {
RefundTransaction tx = response.getTransactions().get(0);
if (tx.getPix() != null) {
String qrCode = tx.getPix().getQrCode(); // QRCode para exibir/ler
String qrCodeBase64 = tx.getPix().getQrCodeBase64(); // QRCode em base64 (imagem)
String endToEndId = tx.getPix().getEndToEndId(); // ID end-to-end do PIX
}
}Se você está usando checkout padrão ou lightbox, informe o smartCheckoutId:
ChargePixRequest request = ChargePixRequest.builder()
.paymentSourceCheckout()
.smartCheckoutId("smart-checkout-uuid-aqui")
.customer(customer)
.phone(phone)
.deviceInformation(device)
.transactions(List.of(transaction))
.build();O webhook já suporta eventos PIX através de WebhookTransaction.getPix() que contém:
qrCodeeqrCodeBase64endToEndIdpayer(dados do pagador quando disponível)
Documentação: Cobrança PIX | PIX.
import com.picpay.checkout.exception.PicPayApiException;
try {
CreatePaymentResponse response = client.createPayment(request);
// ...
} catch (PicPayApiException e) {
int status = e.getHttpStatus();
String body = e.getResponseBody();
String code = e.getBusinessCode();
// tratar conforme status/código
}Este projeto não é oficial do PicPay. Use conforme a documentação e termos do PicPay.